Mercurial > octave-libtiff
comparison scripts/specfun/nchoosek.m @ 30209:54774a713d7c
nchoosek.m: Improve struct input handling for k<n (bug #61119)
* nchoosek.m: replace call to repelems with repelem to handle struct inputs for
k<n. Add k<n struct BIST test.
author | Nicholas R. Jankowski <jankowskin@asme.org> |
---|---|
date | Thu, 23 Sep 2021 21:06:41 -0400 |
parents | aaee7b170cb1 |
children | f5aba4d7e651 |
comparison
equal
deleted
inserted
replaced
30208:8f61866f0f6d | 30209:54774a713d7c |
---|---|
125 C = v(:).'; | 125 C = v(:).'; |
126 elseif (k > n) | 126 elseif (k > n) |
127 C = v(zeros (0, k)); # return 0xk object for Matlab compatibility | 127 C = v(zeros (0, k)); # return 0xk object for Matlab compatibility |
128 elseif (k == 2) | 128 elseif (k == 2) |
129 ## Can do it without transpose. | 129 ## Can do it without transpose. |
130 x = repelems (v(1:n-1), [1:n-1; n-1:-1:1]).'; | 130 x = repelem (v(1:n-1), [n-1:-1:1]).'; |
131 y = cat (1, cellslices (v(:), 2:n, n*ones (1, n-1)){:}); | 131 y = cat (1, cellslices (v(:), 2:n, n*ones (1, n-1)){:}); |
132 C = [x, y]; | 132 C = [x, y]; |
133 elseif (k < n) | 133 elseif (k < n) |
134 v = v(:).'; | 134 v = v(:).'; |
135 C = v(k:n); | 135 C = v(k:n); |
136 l = 1:n-k+1; | 136 l = 1:n-k+1; |
137 for j = 2:k | 137 for j = 2:k |
138 c = columns (C); | 138 c = columns (C); |
139 cA = cellslices (C, l, c*ones (1, n-k+1), 2); | 139 cA = cellslices (C, l, c*ones (1, n-k+1), 2); |
140 l = c-l+1; | 140 l = c-l+1; |
141 b = repelems (v(k-j+1:n-j+1), [1:n-k+1; l]); | 141 b = repelem (v(k-j+1:n-j+1), l); |
142 C = [b; cA{:}]; | 142 C = [b; cA{:}]; |
143 l = cumsum (l); | 143 l = cumsum (l); |
144 l = [1, 1 + l(1:n-k)]; | 144 l = [1, 1 + l(1:n-k)]; |
145 endfor | 145 endfor |
146 C = C.'; | 146 C = C.'; |
158 %!assert (nchoosek ("a":"b", 2), "ab") | 158 %!assert (nchoosek ("a":"b", 2), "ab") |
159 %!assert (nchoosek ({1,2}, 2), {1,2}) | 159 %!assert (nchoosek ({1,2}, 2), {1,2}) |
160 %!test | 160 %!test |
161 %! s(1).a = 1; | 161 %! s(1).a = 1; |
162 %! s(2).a = 2; | 162 %! s(2).a = 2; |
163 %! assert (nchoosek (s, 1), s(:)); | 163 %! assert (nchoosek (s, 1), s(:)); |
164 %! assert (nchoosek (s, 2), s); | 164 %! assert (nchoosek (s, 2), s); |
165 | 165 |
166 # Verify Matlab compatibility of return sizes & types | 166 # Verify Matlab compatibility of return sizes & types |
167 %!test | 167 %!test |
168 %! x = nchoosek (1:2, 0); | 168 %! x = nchoosek (1:2, 0); |
169 %! assert (size (x), [1, 0]); | 169 %! assert (size (x), [1, 0]); |
226 | 226 |
227 %!test | 227 %!test |
228 %! s.a = [1 2 3]; | 228 %! s.a = [1 2 3]; |
229 %! s.b = [4 5 6]; | 229 %! s.b = [4 5 6]; |
230 %! s(2).a = 1; # make s a struct array rather than scalar struct | 230 %! s(2).a = 1; # make s a struct array rather than scalar struct |
231 %! s(3).b = 2; # make s at least three elements for k == 2 test below | |
231 %! x = nchoosek (s, 0); | 232 %! x = nchoosek (s, 0); |
232 %! assert (size (x), [1, 0]); | 233 %! assert (size (x), [1, 0]); |
233 %! assert (isstruct (x)); | 234 %! assert (isstruct (x)); |
234 %! assert (fieldnames (x), {"a"; "b"}); | 235 %! assert (fieldnames (x), {"a"; "b"}); |
235 %! x = nchoosek (s, 3); | 236 %! x = nchoosek (s, 2); |
236 %! assert (size (x), [0, 3]); | 237 %! assert (size (x), [3, 2]); |
238 %! assert (isstruct (x)); | |
239 %! assert (fieldnames (x), {"a"; "b"}); | |
240 %! x = nchoosek (s, 4); | |
241 %! assert (size (x), [0, 4]); | |
237 %! assert (isstruct (x)); | 242 %! assert (isstruct (x)); |
238 %! assert (fieldnames (x), {"a"; "b"}); | 243 %! assert (fieldnames (x), {"a"; "b"}); |
239 | 244 |
240 ## Test input validation | 245 ## Test input validation |
241 %!error <Invalid call> nchoosek () | 246 %!error <Invalid call> nchoosek () |