Mercurial > hg > octave-nkf
comparison scripts/general/accumarray.m @ 7186:800f1fd3ffb8
[project @ 2007-11-26 19:16:07 by jwe]
author | jwe |
---|---|
date | Mon, 26 Nov 2007 19:16:07 +0000 |
parents | 93c65f2a5668 |
children | b93ac0586e4b |
comparison
equal
deleted
inserted
replaced
7185:83cbff53bc96 | 7186:800f1fd3ffb8 |
---|---|
18 | 18 |
19 ## -*- texinfo -*- | 19 ## -*- texinfo -*- |
20 ## @deftypefn {Function File} {} accumarray (@var{subs}, @var{vals}, @var{sz}, @var{fun}, @var{fillval}, @var{issparse}) | 20 ## @deftypefn {Function File} {} accumarray (@var{subs}, @var{vals}, @var{sz}, @var{fun}, @var{fillval}, @var{issparse}) |
21 ## @deftypefnx {Function File} {} accumarray (@var{csubs}, @var{vals}, @dots{}) | 21 ## @deftypefnx {Function File} {} accumarray (@var{csubs}, @var{vals}, @dots{}) |
22 ## | 22 ## |
23 ## Creates an array by accumulating the elements of a vector into the | 23 ## Create an array by accumulating the elements of a vector into the |
24 ## positions of defined by their subscripts. The subscripts are defined by | 24 ## positions defined by their subscripts. The subscripts are defined by |
25 ## the rows of the matrix @var{subs} and the values by @var{vals}. Each row | 25 ## the rows of the matrix @var{subs} and the values by @var{vals}. Each row |
26 ## of @var{subs} corresponds to one of the values in @var{vals}. | 26 ## of @var{subs} corresponds to one of the values in @var{vals}. |
27 ## | 27 ## |
28 ## The size of the matrix will be determined by the subscripts themselves. | 28 ## The size of the matrix will be determined by the subscripts themselves. |
29 ## However, if @var{sz} is defined it determines the matrix size. The length | 29 ## However, if @var{sz} is defined it determines the matrix size. The length |
44 ## | 44 ## |
45 ## An example of the use of @code{accumarray} is: | 45 ## An example of the use of @code{accumarray} is: |
46 ## | 46 ## |
47 ## @example | 47 ## @example |
48 ## @group | 48 ## @group |
49 ## accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2],101:105) | 49 ## accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105) |
50 ## @result{} ans(:,:,1) = [101, 0, 0; 0, 0, 0] | 50 ## @result{} ans(:,:,1) = [101, 0, 0; 0, 0, 0] |
51 ## ans(:,:,2) = [0, 0, 0; 206, 0, 208] | 51 ## ans(:,:,2) = [0, 0, 0; 206, 0, 208] |
52 ## @end group | 52 ## @end group |
53 ## @end example | 53 ## @end example |
54 ## @end deftypefn | 54 ## @end deftypefn |
57 | 57 |
58 if (nargin < 2 || nargin > 6) | 58 if (nargin < 2 || nargin > 6) |
59 print_usage (); | 59 print_usage (); |
60 endif | 60 endif |
61 | 61 |
62 if (iscell(subs)) | 62 if (iscell (subs)) |
63 subs = cell2mat (cellfun (@(x) x(:), subs, 'UniformOutput', false)); | 63 subs = cell2mat (cellfun (@(x) x(:), subs, 'UniformOutput', false)); |
64 endif | 64 endif |
65 ndims = size (subs, 2); | 65 ndims = size (subs, 2); |
66 | 66 |
67 if (nargin < 3 || isempty (sz)) | 67 if (nargin < 3 || isempty (sz)) |
68 sz = max (subs); | 68 sz = max (subs); |
69 if (isscalar(sz)) | 69 if (isscalar(sz)) |
70 sz = [sz, 1]; | 70 sz = [sz, 1]; |
71 endif | 71 endif |
72 else | 72 elseif (length (sz) != ndims |
73 if (length (sz) != ndims) | 73 && (ndims != 1 || length (sz) != 2 || sz(2) != 1)) |
74 error ("accumarray: inconsistent dimensions"); | 74 error ("accumarray: inconsistent dimensions"); |
75 endif | |
76 endif | 75 endif |
77 | 76 |
78 if (nargin < 4 || isempty (fun)) | 77 if (nargin < 4 || isempty (fun)) |
79 fun = @sum; | 78 fun = @sum; |
80 endif | 79 endif |
84 endif | 83 endif |
85 | 84 |
86 if (nargin < 6 || isempty (isspar)) | 85 if (nargin < 6 || isempty (isspar)) |
87 isspar = false; | 86 isspar = false; |
88 endif | 87 endif |
89 if (isspar) | 88 |
90 if (ndims > 2) | 89 if (isspar && ndims > 2) |
91 error ("Can not have more than 2 dimensions in a sparse matrix"); | 90 error ("accumarray: sparse matrices limited to 2 dimensions"); |
92 endif | |
93 endif | 91 endif |
94 | 92 |
95 [subs, idx] = sortrows (subs); | 93 [subs, idx] = sortrows (subs); |
96 if (isscalar (val)) | 94 if (isscalar (val)) |
97 val = val * ones (size (idx)); | 95 val = val * ones (size (idx)); |
98 else | 96 else |
99 val = val(idx); | 97 val = val(idx); |
100 endif | 98 endif |
101 cidx = find([true; (sum (abs (diff (subs)), 2) != 0)]); | 99 cidx = find ([true; (sum (abs (diff (subs)), 2) != 0)]); |
102 idx = cell (1, ndims); | 100 idx = cell (1, ndims); |
103 for i = 1:ndims | 101 for i = 1:ndims |
104 idx{i} = subs (cidx, i); | 102 idx{i} = subs (cidx, i); |
105 endfor | 103 endfor |
106 x = cellfun (fun, mat2cell (val(:), diff ([cidx; length(val) + 1]))); | 104 x = cellfun (fun, mat2cell (val(:), diff ([cidx; length(val) + 1]))); |
107 if (isspar && fillval == 0) | 105 if (isspar && fillval == 0) |
108 A = sparse (idx{1}, idx{2}, x, sz(1), sz(2)); | 106 A = sparse (idx{1}, idx{2}, x, sz(1), sz(2)); |
109 else | 107 else |
110 if (iscell (x)) | 108 if (iscell (x)) |
111 ## Why did matlab choose to reverse the order of the elements | 109 ## Why did matlab choose to reverse the order of the elements |
112 x = cellfun (@(x) flipud(x(:)), x, 'UniformOutput', false); | 110 x = cellfun (@(x) flipud (x(:)), x, 'UniformOutput', false); |
113 A = cell (sz); | 111 A = cell (sz); |
114 elseif (fillval == 0) | 112 elseif (fillval == 0) |
115 A = zeros (sz, class(x)); | 113 A = zeros (sz, class (x)); |
116 else | 114 else |
117 A = fillval .* ones (sz); | 115 A = fillval .* ones (sz); |
118 endif | 116 endif |
119 A (sub2ind (sz, idx{:})) = x; | 117 A(sub2ind (sz, idx{:})) = x; |
120 endif | 118 endif |
121 endfunction | 119 endfunction |
122 | 120 |
123 %!error (accumarray (1:5)) | 121 %!error (accumarray (1:5)) |
124 %!error (accumarray ([1,2,3],1:2)) | 122 %!error (accumarray ([1,2,3],1:2)) |