Mercurial > octave
comparison scripts/specfun/nchoosek.m @ 30204:1cd077e9f127
allow nchoosek to accept character vectors (bug #61199)
* nchoosek.m: Allow input of possible values to be a character array.
Ensure output is the same type as array of possible values. New
tests.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 23 Sep 2021 00:00:12 -0400 |
parents | 7854d5752dd2 |
children | 23a907b2dbd5 |
comparison
equal
deleted
inserted
replaced
30203:75fb18f0469a | 30204:1cd077e9f127 |
---|---|
92 | 92 |
93 function C = nchoosek (v, k) | 93 function C = nchoosek (v, k) |
94 | 94 |
95 if (nargin != 2 | 95 if (nargin != 2 |
96 || ! (isreal (k) && isscalar (k)) | 96 || ! (isreal (k) && isscalar (k)) |
97 || ! (isnumeric (v) && isvector (v))) | 97 || ! ((isnumeric (v) || ischar (v)) && isvector (v))) |
98 print_usage (); | 98 print_usage (); |
99 endif | 99 endif |
100 if (k < 0 || k != fix (k)) | 100 if (k < 0 || k != fix (k)) |
101 error ("nchoosek: K must be an integer >= 0"); | 101 error ("nchoosek: K must be an integer >= 0"); |
102 elseif (isscalar (v) && (iscomplex (v) || v < k || v < 0 || v != fix (v))) | 102 elseif (isscalar (v) && (iscomplex (v) || v < k || v < 0 || v != fix (v))) |
111 C = round (prod ((v-k+1:v)./(1:k))); | 111 C = round (prod ((v-k+1:v)./(1:k))); |
112 if (C*2*k*eps >= 0.5) | 112 if (C*2*k*eps >= 0.5) |
113 warning ("nchoosek: possible loss of precision"); | 113 warning ("nchoosek: possible loss of precision"); |
114 endif | 114 endif |
115 elseif (k == 0) | 115 elseif (k == 0) |
116 C = zeros (1,0); | 116 if (is_sq_string (v)) |
117 C = resize ('', 1, 0); | |
118 elseif (is_dq_string (v)) | |
119 C = resize ("", 1, 0); | |
120 else | |
121 C = zeros (1, 0, class (v)); | |
122 endif | |
117 elseif (k == 1) | 123 elseif (k == 1) |
118 C = v(:); | 124 C = v(:); |
119 elseif (k == n) | 125 elseif (k == n) |
120 C = v(:).'; | 126 C = v(:).'; |
121 elseif (k > n) | 127 elseif (k > n) |
122 C = zeros (0, k, class (v)); | 128 if (is_sq_string (v)) |
129 C = resize ('', 0, k); | |
130 elseif (is_dq_string (v)) | |
131 C = resize ("", 0, k); | |
132 else | |
133 C = zeros (0, k, class (v)); | |
134 endif | |
123 elseif (k == 2) | 135 elseif (k == 2) |
124 ## Can do it without transpose. | 136 ## Can do it without transpose. |
125 x = repelems (v(1:n-1), [1:n-1; n-1:-1:1]).'; | 137 x = repelems (v(1:n-1), [1:n-1; n-1:-1:1]).'; |
126 y = cat (1, cellslices (v(:), 2:n, n*ones (1, n-1)){:}); | 138 y = cat (1, cellslices (v(:), 2:n, n*ones (1, n-1)){:}); |
127 C = [x, y]; | 139 C = [x, y]; |
152 %!error <Invalid call> nchoosek () | 164 %!error <Invalid call> nchoosek () |
153 %!error <Invalid call> nchoosek (1) | 165 %!error <Invalid call> nchoosek (1) |
154 | 166 |
155 %!error nchoosek (100, 2i) | 167 %!error nchoosek (100, 2i) |
156 %!error nchoosek (100, [2 3]) | 168 %!error nchoosek (100, [2 3]) |
157 %!error nchoosek ("100", 45) | |
158 %!error nchoosek (100*ones (2, 2), 45) | 169 %!error nchoosek (100*ones (2, 2), 45) |
159 %!error <K must be an integer .= 0> nchoosek (100, -45) | 170 %!error <K must be an integer .= 0> nchoosek (100, -45) |
160 %!error <K must be an integer .= 0> nchoosek (100, 45.5) | 171 %!error <K must be an integer .= 0> nchoosek (100, 45.5) |
161 %!error <N must be a non-negative integer .= K> nchoosek (100i, 2) | 172 %!error <N must be a non-negative integer .= K> nchoosek (100i, 2) |
162 %!error <N must be a non-negative integer .= K> nchoosek (100, 145) | 173 %!error <N must be a non-negative integer .= K> nchoosek (100, 145) |
163 %!error <N must be a non-negative integer .= K> nchoosek (-100, 45) | 174 %!error <N must be a non-negative integer .= K> nchoosek (-100, 45) |
164 %!error <N must be a non-negative integer .= K> nchoosek (100.5, 45) | 175 %!error <N must be a non-negative integer .= K> nchoosek (100.5, 45) |
165 %!warning <possible loss of precision> nchoosek (100, 45); | 176 %!warning <possible loss of precision> nchoosek (100, 45); |
177 | |
178 %!assert (nchoosek ('a':'b', 2), 'ab') | |
179 %!assert (nchoosek ("a":"b", 2), "ab") | |
180 | |
181 %!test | |
182 %! x = nchoosek ('a':'b', 3); | |
183 %! assert (size (x), [0, 3]); | |
184 %! assert (is_sq_string (x)); | |
185 %! x = nchoosek ('a':'b', 0); | |
186 %! assert (size (x), [1, 0]); | |
187 %! assert (is_sq_string (x)); | |
188 %! | |
189 %! x = nchoosek ("a":"b", 3); | |
190 %! assert (size (x), [0, 3]); | |
191 %! assert (is_dq_string (x)); | |
192 %! x = nchoosek ("a":"b", 0); | |
193 %! assert (size (x), [1, 0]); | |
194 %! assert (is_dq_string (x)); | |
195 %! | |
196 %! x = nchoosek (uint8(1):uint8(2), 3); | |
197 %! assert (size (x), [0, 3]); | |
198 %! assert (class (x), "uint8"); | |
199 %! x = nchoosek (uint8(1):uint8(2), 0); | |
200 %! assert (size (x), [1, 0]); | |
201 %! assert (class (x), "uint8"); |