File: | libinterp/corefcn/find.cc |
Location: | line 241, column 7 |
Description: | Value stored to 'n_to_find' is never read |
1 | /* |
2 | |
3 | Copyright (C) 1996-2013 John W. Eaton |
4 | |
5 | This file is part of Octave. |
6 | |
7 | Octave is free software; you can redistribute it and/or modify it |
8 | under the terms of the GNU General Public License as published by the |
9 | Free Software Foundation; either version 3 of the License, or (at your |
10 | option) any later version. |
11 | |
12 | Octave is distributed in the hope that it will be useful, but WITHOUT |
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
15 | for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with Octave; see the file COPYING. If not, see |
19 | <http://www.gnu.org/licenses/>. |
20 | |
21 | */ |
22 | |
23 | #ifdef HAVE_CONFIG_H1 |
24 | #include <config.h> |
25 | #endif |
26 | |
27 | #include "quit.h" |
28 | |
29 | #include "defun.h" |
30 | #include "error.h" |
31 | #include "gripes.h" |
32 | #include "oct-obj.h" |
33 | |
34 | // Find at most N_TO_FIND nonzero elements in NDA. Search forward if |
35 | // DIRECTION is 1, backward if it is -1. NARGOUT is the number of |
36 | // output arguments. If N_TO_FIND is -1, find all nonzero elements. |
37 | |
38 | template <typename T> |
39 | octave_value_list |
40 | find_nonzero_elem_idx (const Array<T>& nda, int nargout, |
41 | octave_idx_type n_to_find, int direction) |
42 | { |
43 | octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ()); |
44 | |
45 | Array<octave_idx_type> idx; |
46 | if (n_to_find >= 0) |
47 | idx = nda.find (n_to_find, direction == -1); |
48 | else |
49 | idx = nda.find (); |
50 | |
51 | // The maximum element is always at the end. |
52 | octave_idx_type iext = idx.is_empty () ? 0 : idx.xelem (idx.numel () - 1) + 1; |
53 | |
54 | switch (nargout) |
55 | { |
56 | default: |
57 | case 3: |
58 | retval(2) = Array<T> (nda.index (idx_vector (idx))); |
59 | // Fall through! |
60 | |
61 | case 2: |
62 | { |
63 | Array<octave_idx_type> jdx (idx.dims ()); |
64 | octave_idx_type n = idx.length (), nr = nda.rows (); |
65 | for (octave_idx_type i = 0; i < n; i++) |
66 | { |
67 | jdx.xelem (i) = idx.xelem (i) / nr; |
68 | idx.xelem (i) %= nr; |
69 | } |
70 | iext = -1; |
71 | retval(1) = idx_vector (jdx, -1); |
72 | } |
73 | // Fall through! |
74 | |
75 | case 1: |
76 | case 0: |
77 | retval(0) = idx_vector (idx, iext); |
78 | break; |
79 | } |
80 | |
81 | return retval; |
82 | } |
83 | |
84 | template <typename T> |
85 | octave_value_list |
86 | find_nonzero_elem_idx (const Sparse<T>& v, int nargout, |
87 | octave_idx_type n_to_find, int direction) |
88 | { |
89 | octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ()); |
90 | |
91 | |
92 | octave_idx_type nc = v.cols (); |
93 | octave_idx_type nr = v.rows (); |
94 | octave_idx_type nz = v.nnz (); |
95 | |
96 | // Search in the default range. |
97 | octave_idx_type start_nc = -1; |
98 | octave_idx_type end_nc = -1; |
99 | octave_idx_type count; |
100 | |
101 | // Search for the range to search |
102 | if (n_to_find < 0) |
103 | { |
104 | start_nc = 0; |
105 | end_nc = nc; |
106 | n_to_find = nz; |
107 | count = nz; |
108 | } |
109 | else if (direction > 0) |
110 | { |
111 | for (octave_idx_type j = 0; j < nc; j++) |
112 | { |
113 | OCTAVE_QUIToctave_quit (); |
114 | if (v.cidx (j) == 0 && v.cidx (j+1) != 0) |
115 | start_nc = j; |
116 | if (v.cidx (j+1) >= n_to_find) |
117 | { |
118 | end_nc = j + 1; |
119 | break; |
120 | } |
121 | } |
122 | } |
123 | else |
124 | { |
125 | for (octave_idx_type j = nc; j > 0; j--) |
126 | { |
127 | OCTAVE_QUIToctave_quit (); |
128 | if (v.cidx (j) == nz && v.cidx (j-1) != nz) |
129 | end_nc = j; |
130 | if (nz - v.cidx (j-1) >= n_to_find) |
131 | { |
132 | start_nc = j - 1; |
133 | break; |
134 | } |
135 | } |
136 | } |
137 | |
138 | count = (n_to_find > v.cidx (end_nc) - v.cidx (start_nc) ? |
139 | v.cidx (end_nc) - v.cidx (start_nc) : n_to_find); |
140 | |
141 | // If the original argument was a row vector, force a row vector of |
142 | // the overall indices to be returned. But see below for scalar |
143 | // case... |
144 | |
145 | octave_idx_type result_nr = count; |
146 | octave_idx_type result_nc = 1; |
147 | |
148 | bool scalar_arg = false; |
149 | |
150 | if (v.rows () == 1) |
151 | { |
152 | result_nr = 1; |
153 | result_nc = count; |
154 | |
155 | scalar_arg = (v.columns () == 1); |
156 | } |
157 | |
158 | Matrix idx (result_nr, result_nc); |
159 | |
160 | Matrix i_idx (result_nr, result_nc); |
161 | Matrix j_idx (result_nr, result_nc); |
162 | |
163 | Array<T> val (dim_vector (result_nr, result_nc)); |
164 | |
165 | if (count > 0) |
166 | { |
167 | // Search for elements to return. Only search the region where |
168 | // there are elements to be found using the count that we want |
169 | // to find. |
170 | for (octave_idx_type j = start_nc, cx = 0; j < end_nc; j++) |
171 | for (octave_idx_type i = v.cidx (j); i < v.cidx (j+1); i++ ) |
172 | { |
173 | OCTAVE_QUIToctave_quit (); |
174 | if (direction < 0 && i < nz - count) |
175 | continue; |
176 | i_idx(cx) = static_cast<double> (v.ridx (i) + 1); |
177 | j_idx(cx) = static_cast<double> (j + 1); |
178 | idx(cx) = j * nr + v.ridx (i) + 1; |
179 | val(cx) = v.data(i); |
180 | cx++; |
181 | if (cx == count) |
182 | break; |
183 | } |
184 | } |
185 | else if (scalar_arg) |
186 | { |
187 | idx.resize (0, 0); |
188 | |
189 | i_idx.resize (0, 0); |
190 | j_idx.resize (0, 0); |
191 | |
192 | val.resize (dim_vector (0, 0)); |
193 | } |
194 | |
195 | switch (nargout) |
196 | { |
197 | case 0: |
198 | case 1: |
199 | retval(0) = idx; |
200 | break; |
201 | |
202 | case 5: |
203 | retval(4) = nc; |
204 | // Fall through |
205 | |
206 | case 4: |
207 | retval(3) = nr; |
208 | // Fall through |
209 | |
210 | case 3: |
211 | retval(2) = val; |
212 | // Fall through! |
213 | |
214 | case 2: |
215 | retval(1) = j_idx; |
216 | retval(0) = i_idx; |
217 | break; |
218 | |
219 | default: |
220 | panic_impossible ()panic ("impossible state reached in file '%s' at line %d", "corefcn/find.cc" , 220); |
221 | break; |
222 | } |
223 | |
224 | return retval; |
225 | } |
226 | |
227 | octave_value_list |
228 | find_nonzero_elem_idx (const PermMatrix& v, int nargout, |
229 | octave_idx_type n_to_find, int direction) |
230 | { |
231 | // There are far fewer special cases to handle for a PermMatrix. |
232 | octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ()); |
233 | |
234 | octave_idx_type nc = v.cols (); |
235 | octave_idx_type start_nc, count; |
236 | |
237 | // Determine the range to search. |
238 | if (n_to_find < 0 || n_to_find >= nc) |
239 | { |
240 | start_nc = 0; |
241 | n_to_find = nc; |
Value stored to 'n_to_find' is never read | |
242 | count = nc; |
243 | } |
244 | else if (direction > 0) |
245 | { |
246 | start_nc = 0; |
247 | count = n_to_find; |
248 | } |
249 | else |
250 | { |
251 | start_nc = nc - n_to_find; |
252 | count = n_to_find; |
253 | } |
254 | |
255 | bool scalar_arg = (v.rows () == 1 && v.cols () == 1); |
256 | |
257 | Matrix idx (count, 1); |
258 | Matrix i_idx (count, 1); |
259 | Matrix j_idx (count, 1); |
260 | // Every value is 1. |
261 | Array<double> val (dim_vector (count, 1), 1.0); |
262 | |
263 | if (count > 0) |
264 | { |
265 | const octave_idx_type* p = v.data (); |
266 | if (v.is_col_perm ()) |
267 | { |
268 | for (octave_idx_type k = 0; k < count; k++) |
269 | { |
270 | OCTAVE_QUIToctave_quit (); |
271 | const octave_idx_type j = start_nc + k; |
272 | const octave_idx_type i = p[j]; |
273 | i_idx(k) = static_cast<double> (1+i); |
274 | j_idx(k) = static_cast<double> (1+j); |
275 | idx(k) = j * nc + i + 1; |
276 | } |
277 | } |
278 | else |
279 | { |
280 | for (octave_idx_type k = 0; k < count; k++) |
281 | { |
282 | OCTAVE_QUIToctave_quit (); |
283 | const octave_idx_type i = start_nc + k; |
284 | const octave_idx_type j = p[i]; |
285 | // Scatter into the index arrays according to |
286 | // j adjusted by the start point. |
287 | const octave_idx_type koff = j - start_nc; |
288 | i_idx(koff) = static_cast<double> (1+i); |
289 | j_idx(koff) = static_cast<double> (1+j); |
290 | idx(koff) = j * nc + i + 1; |
291 | } |
292 | } |
293 | } |
294 | else if (scalar_arg) |
295 | { |
296 | // Same odd compatibility case as the other overrides. |
297 | idx.resize (0, 0); |
298 | i_idx.resize (0, 0); |
299 | j_idx.resize (0, 0); |
300 | val.resize (dim_vector (0, 0)); |
301 | } |
302 | |
303 | switch (nargout) |
304 | { |
305 | case 0: |
306 | case 1: |
307 | retval(0) = idx; |
308 | break; |
309 | |
310 | case 5: |
311 | retval(4) = nc; |
312 | // Fall through |
313 | |
314 | case 4: |
315 | retval(3) = nc; |
316 | // Fall through |
317 | |
318 | case 3: |
319 | retval(2) = val; |
320 | // Fall through! |
321 | |
322 | case 2: |
323 | retval(1) = j_idx; |
324 | retval(0) = i_idx; |
325 | break; |
326 | |
327 | default: |
328 | panic_impossible ()panic ("impossible state reached in file '%s' at line %d", "corefcn/find.cc" , 328); |
329 | break; |
330 | } |
331 | |
332 | return retval; |
333 | } |
334 | |
335 | DEFUN (find, args, nargout,octave_value_list Ffind (const octave_value_list& args, int nargout) |
336 | "-*- texinfo -*-\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
337 | @deftypefn {Built-in Function} {@var{idx} =} find (@var{x})\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
338 | @deftypefnx {Built-in Function} {@var{idx} =} find (@var{x}, @var{n})\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
339 | @deftypefnx {Built-in Function} {@var{idx} =} find (@var{x}, @var{n}, @var{direction})\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
340 | @deftypefnx {Built-in Function} {[i, j] =} find (@dots{})\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
341 | @deftypefnx {Built-in Function} {[i, j, v] =} find (@dots{})\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
342 | Return a vector of indices of nonzero elements of a matrix, as a row if\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
343 | @var{x} is a row vector or as a column otherwise. To obtain a single index\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
344 | for each matrix element, Octave pretends that the columns of a matrix form\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
345 | one long vector (like Fortran arrays are stored). For example:\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
346 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
347 | @example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
348 | @group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
349 | find (eye (2))\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
350 | @result{} [ 1; 4 ]\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
351 | @end group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
352 | @end example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
353 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
354 | If two outputs are requested, @code{find} returns the row and column\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
355 | indices of nonzero elements of a matrix. For example:\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
356 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
357 | @example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
358 | @group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
359 | [i, j] = find (2 * eye (2))\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
360 | @result{} i = [ 1; 2 ]\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
361 | @result{} j = [ 1; 2 ]\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
362 | @end group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
363 | @end example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
364 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
365 | If three outputs are requested, @code{find} also returns a vector\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
366 | containing the nonzero values. For example:\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
367 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
368 | @example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
369 | @group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
370 | [i, j, v] = find (3 * eye (2))\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
371 | @result{} i = [ 1; 2 ]\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
372 | @result{} j = [ 1; 2 ]\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
373 | @result{} v = [ 3; 3 ]\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
374 | @end group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
375 | @end example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
376 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
377 | If two inputs are given, @var{n} indicates the maximum number of\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
378 | elements to find from the beginning of the matrix or vector.\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
379 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
380 | If three inputs are given, @var{direction} should be one of\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
381 | @qcode{\"first\"} or @qcode{\"last\"}, requesting only the first or last\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
382 | @var{n} indices, respectively. However, the indices are always returned in\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
383 | ascending order.\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
384 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
385 | Note that this function is particularly useful for sparse matrices, as\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
386 | it extracts the non-zero elements as vectors, which can then be used to\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
387 | create the original matrix. For example:\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
388 | \n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
389 | @example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
390 | @group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
391 | sz = size (a);\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
392 | [i, j, v] = find (a);\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
393 | b = sparse (i, j, v, sz(1), sz(2));\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
394 | @end group\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
395 | @end example\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
396 | @seealso{nonzeros}\n\octave_value_list Ffind (const octave_value_list& args, int nargout) |
397 | @end deftypefn")octave_value_list Ffind (const octave_value_list& args, int nargout) |
398 | { |
399 | octave_value_list retval; |
400 | |
401 | int nargin = args.length (); |
402 | |
403 | if (nargin > 3 || nargin < 1) |
404 | { |
405 | print_usage (); |
406 | return retval; |
407 | } |
408 | |
409 | // Setup the default options. |
410 | octave_idx_type n_to_find = -1; |
411 | if (nargin > 1) |
412 | { |
413 | double val = args(1).scalar_value (); |
414 | |
415 | if (error_state || (val < 0 || (! xisinf (val) && val != xround (val)))) |
416 | { |
417 | error ("find: N must be a non-negative integer"); |
418 | return retval; |
419 | } |
420 | else if (! xisinf (val)) |
421 | n_to_find = val; |
422 | } |
423 | |
424 | // Direction to do the searching (1 == forward, -1 == reverse). |
425 | int direction = 1; |
426 | if (nargin > 2) |
427 | { |
428 | direction = 0; |
429 | |
430 | std::string s_arg = args(2).string_value (); |
431 | |
432 | if (! error_state) |
433 | { |
434 | if (s_arg == "first") |
435 | direction = 1; |
436 | else if (s_arg == "last") |
437 | direction = -1; |
438 | } |
439 | |
440 | if (direction == 0) |
441 | { |
442 | error ("find: DIRECTION must be \"first\" or \"last\""); |
443 | return retval; |
444 | } |
445 | } |
446 | |
447 | octave_value arg = args(0); |
448 | |
449 | if (arg.is_bool_type ()) |
450 | { |
451 | if (arg.is_sparse_type ()) |
452 | { |
453 | SparseBoolMatrix v = arg.sparse_bool_matrix_value (); |
454 | |
455 | if (! error_state) |
456 | retval = find_nonzero_elem_idx (v, nargout, |
457 | n_to_find, direction); |
458 | } |
459 | else if (nargout <= 1 && n_to_find == -1 && direction == 1) |
460 | { |
461 | // This case is equivalent to extracting indices from a logical |
462 | // matrix. Try to reuse the possibly cached index vector. |
463 | retval(0) = arg.index_vector ().unmask (); |
464 | } |
465 | else |
466 | { |
467 | boolNDArray v = arg.bool_array_value (); |
468 | |
469 | if (! error_state) |
470 | retval = find_nonzero_elem_idx (v, nargout, |
471 | n_to_find, direction); |
472 | } |
473 | } |
474 | else if (arg.is_integer_type ()) |
475 | { |
476 | #define DO_INT_BRANCH(INTT)else if (arg.is_INTT_type ()) { INTTNDArray v = arg.INTT_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } \ |
477 | else if (arg.is_ ## INTT ## _type ()) \ |
478 | { \ |
479 | INTT ## NDArray v = arg.INTT ## _array_value (); \ |
480 | \ |
481 | if (! error_state) \ |
482 | retval = find_nonzero_elem_idx (v, nargout, \ |
483 | n_to_find, direction);\ |
484 | } |
485 | |
486 | if (false) |
487 | ; |
488 | DO_INT_BRANCH (int8)else if (arg.is_int8_type ()) { int8NDArray v = arg.int8_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
489 | DO_INT_BRANCH (int16)else if (arg.is_int16_type ()) { int16NDArray v = arg.int16_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
490 | DO_INT_BRANCH (int32)else if (arg.is_int32_type ()) { int32NDArray v = arg.int32_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
491 | DO_INT_BRANCH (int64)else if (arg.is_int64_type ()) { int64NDArray v = arg.int64_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
492 | DO_INT_BRANCH (uint8)else if (arg.is_uint8_type ()) { uint8NDArray v = arg.uint8_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
493 | DO_INT_BRANCH (uint16)else if (arg.is_uint16_type ()) { uint16NDArray v = arg.uint16_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
494 | DO_INT_BRANCH (uint32)else if (arg.is_uint32_type ()) { uint32NDArray v = arg.uint32_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
495 | DO_INT_BRANCH (uint64)else if (arg.is_uint64_type ()) { uint64NDArray v = arg.uint64_array_value (); if (! error_state) retval = find_nonzero_elem_idx (v, nargout , n_to_find, direction); } |
496 | else |
497 | panic_impossible ()panic ("impossible state reached in file '%s' at line %d", "corefcn/find.cc" , 497); |
498 | } |
499 | else if (arg.is_sparse_type ()) |
500 | { |
501 | if (arg.is_real_type ()) |
502 | { |
503 | SparseMatrix v = arg.sparse_matrix_value (); |
504 | |
505 | if (! error_state) |
506 | retval = find_nonzero_elem_idx (v, nargout, |
507 | n_to_find, direction); |
508 | } |
509 | else if (arg.is_complex_type ()) |
510 | { |
511 | SparseComplexMatrix v = arg.sparse_complex_matrix_value (); |
512 | |
513 | if (! error_state) |
514 | retval = find_nonzero_elem_idx (v, nargout, |
515 | n_to_find, direction); |
516 | } |
517 | else |
518 | gripe_wrong_type_arg ("find", arg); |
519 | } |
520 | else if (arg.is_perm_matrix ()) |
521 | { |
522 | PermMatrix P = arg.perm_matrix_value (); |
523 | |
524 | if (! error_state) |
525 | retval = find_nonzero_elem_idx (P, nargout, n_to_find, direction); |
526 | } |
527 | else if (arg.is_string ()) |
528 | { |
529 | charNDArray chnda = arg.char_array_value (); |
530 | |
531 | if (! error_state) |
532 | retval = find_nonzero_elem_idx (chnda, nargout, n_to_find, direction); |
533 | } |
534 | else if (arg.is_single_type ()) |
535 | { |
536 | if (arg.is_real_type ()) |
537 | { |
538 | FloatNDArray nda = arg.float_array_value (); |
539 | |
540 | if (! error_state) |
541 | retval = find_nonzero_elem_idx (nda, nargout, n_to_find, |
542 | direction); |
543 | } |
544 | else if (arg.is_complex_type ()) |
545 | { |
546 | FloatComplexNDArray cnda = arg.float_complex_array_value (); |
547 | |
548 | if (! error_state) |
549 | retval = find_nonzero_elem_idx (cnda, nargout, n_to_find, |
550 | direction); |
551 | } |
552 | } |
553 | else if (arg.is_real_type ()) |
554 | { |
555 | NDArray nda = arg.array_value (); |
556 | |
557 | if (! error_state) |
558 | retval = find_nonzero_elem_idx (nda, nargout, n_to_find, direction); |
559 | } |
560 | else if (arg.is_complex_type ()) |
561 | { |
562 | ComplexNDArray cnda = arg.complex_array_value (); |
563 | |
564 | if (! error_state) |
565 | retval = find_nonzero_elem_idx (cnda, nargout, n_to_find, direction); |
566 | } |
567 | else |
568 | gripe_wrong_type_arg ("find", arg); |
569 | |
570 | return retval; |
571 | } |
572 | |
573 | /* |
574 | %!assert (find (char ([0, 97])), 2) |
575 | %!assert (find ([1, 0, 1, 0, 1]), [1, 3, 5]) |
576 | %!assert (find ([1; 0; 3; 0; 1]), [1; 3; 5]) |
577 | %!assert (find ([0, 0, 2; 0, 3, 0; -1, 0, 0]), [3; 5; 7]) |
578 | |
579 | %!test |
580 | %! [i, j, v] = find ([0, 0, 2; 0, 3, 0; -1, 0, 0]); |
581 | %! |
582 | %! assert (i, [3; 2; 1]); |
583 | %! assert (j, [1; 2; 3]); |
584 | %! assert (v, [-1; 3; 2]); |
585 | |
586 | %!assert (find (single ([1, 0, 1, 0, 1])), [1, 3, 5]) |
587 | %!assert (find (single ([1; 0; 3; 0; 1])), [1; 3; 5]) |
588 | %!assert (find (single ([0, 0, 2; 0, 3, 0; -1, 0, 0])), [3; 5; 7]) |
589 | |
590 | %!test |
591 | %! [i, j, v] = find (single ([0, 0, 2; 0, 3, 0; -1, 0, 0])); |
592 | %! |
593 | %! assert (i, [3; 2; 1]); |
594 | %! assert (j, [1; 2; 3]); |
595 | %! assert (v, single ([-1; 3; 2])); |
596 | |
597 | %!test |
598 | %! pcol = [5 1 4 3 2]; |
599 | %! P = eye (5) (:, pcol); |
600 | %! [i, j, v] = find (P); |
601 | %! [ifull, jfull, vfull] = find (full (P)); |
602 | %! assert (i, ifull); |
603 | %! assert (j, jfull); |
604 | %! assert (all (v == 1)); |
605 | |
606 | %!test |
607 | %! prow = [5 1 4 3 2]; |
608 | %! P = eye (5) (prow, :); |
609 | %! [i, j, v] = find (P); |
610 | %! [ifull, jfull, vfull] = find (full (P)); |
611 | %! assert (i, ifull); |
612 | %! assert (j, jfull); |
613 | %! assert (all (v == 1)); |
614 | |
615 | %!assert (find ([2 0 1 0 5 0], 1), 1) |
616 | %!assert (find ([2 0 1 0 5 0], 2, "last"), [3, 5]) |
617 | |
618 | %!assert (find ([2 0 1 0 5 0], Inf), [1, 3, 5]) |
619 | %!assert (find ([2 0 1 0 5 0], Inf, "last"), [1, 3, 5]) |
620 | |
621 | %!error find () |
622 | */ |