47 return (str.find (c) != std::string::npos
48 || str.find (std::toupper (c)) != std::string::npos);
52 struct icmp_char_lt :
public std::binary_function<char, char, bool>
55 {
return std::toupper (x) < std::toupper (y); }
58 struct icmp_char_gt :
public std::binary_function<char, char, bool>
61 {
return std::toupper (x) > std::toupper (y); }
69 stri_comp_lt (
const std::string& a,
const std::string& b)
71 return std::lexicographical_compare (a.begin (), a.end (),
78 stri_comp_gt (
const std::string& a,
const std::string& b)
80 return std::lexicographical_compare (a.begin (), a.end (),
93 if (n > 1 && desc_comp (array (0), array (n-1)))
103 #define INT_ARRAY_LOOKUP(TYPE) \
104 (table.is_ ## TYPE ## _type () && y.is_ ## TYPE ## _type ()) \
105 retval = do_numeric_lookup (table.TYPE ## _array_value (), \
106 y.TYPE ## _array_value (), \
107 left_inf, right_inf, \
108 match_idx, match_bool);
109 template <
class ArrayT>
112 bool left_inf,
bool right_inf,
113 bool match_idx,
bool match_bool)
127 match.xelem (i) = j != 0 && values(i) == array(j-1);
132 else if (match_idx || left_inf || right_inf)
141 ridx.xelem (i) = (j != 0 && values(i) == array(j-1)) ? j : 0;
146 else if (left_inf && right_inf)
191 @deftypefn {Built-in Function} {@var{idx} =} lookup (@var{table}, @var{y})\n\
192 @deftypefnx {Built-in Function} {@var{idx} =} lookup (@var{table}, @var{y}, @var{opt})\n\
193 Lookup values in a sorted table. Usually used as a prelude to\n\
196 If table is increasing and @code{idx = lookup (table, y)}, then\n\
197 @code{table(idx(i)) <= y(i) < table(idx(i+1))} for all @code{y(i)}\n\
198 within the table. If @code{y(i) < table(1)} then\n\
199 @code{idx(i)} is 0. If @code{y(i) >= table(end)} or @code{isnan (y(i))} then\n\
200 @code{idx(i)} is @code{n}.\n\
202 If the table is decreasing, then the tests are reversed.\n\
203 For non-strictly monotonic tables, empty intervals are always skipped.\n\
204 The result is undefined if @var{table} is not monotonic, or if\n\
205 @var{table} contains a NaN.\n\
207 The complexity of the lookup is O(M*log(N)) where N is the size of\n\
208 @var{table} and M is the size of @var{y}. In the special case when @var{y}\n\
209 is also sorted, the complexity is O(min(M*log(N),M+N)).\n\
211 @var{table} and @var{y} can also be cell arrays of strings\n\
212 (or @var{y} can be a single string). In this case, string lookup\n\
213 is performed using lexicographical comparison.\n\
215 If @var{opts} is specified, it must be a string with letters indicating\n\
216 additional options.\n\
220 @code{table(idx(i)) == val(i)} if @code{val(i)}\n\
221 occurs in table; otherwise, @code{idx(i)} is zero.\n\
224 @code{idx(i)} is a logical 1 or 0, indicating whether\n\
225 @code{val(i)} is contained in table or not.\n\
228 For numeric lookups\n\
229 the leftmost subinterval shall be extended to infinity (i.e., all indices\n\
233 For numeric lookups\n\
234 the rightmost subinterval shall be extended to infinity (i.e., all indices\n\
241 int nargin = args.
length ();
243 if (nargin < 2 || nargin > 3 || (nargin == 3 && ! args(2).is_string ()))
251 warning (
"lookup: table is not a vector");
255 bool str_case = table.
is_cellstr () && (y.is_string () || y.is_cellstr ());
256 bool left_inf =
false;
257 bool right_inf =
false;
258 bool match_idx =
false;
259 bool match_bool =
false;
263 std::string opt = args(2).string_value ();
268 if (opt.find_first_not_of (
"lrmb") != std::string::npos)
270 error (
"lookup: unrecognized option: %c",
271 opt[opt.find_first_not_of (
"lrmb")]);
276 if ((match_idx || match_bool) && (left_inf || right_inf))
277 error (
"lookup: m, b cannot be specified with l or r");
278 else if (match_idx && match_bool)
279 error (
"lookup: only one of m or b can be specified");
280 else if (str_case && (left_inf || right_inf))
281 error (
"lookup: l, r are not recognized for string lookups");
293 table = table.
abs ();
295 if (y.is_complex_type ())
311 y.char_array_value (),
313 match_idx, match_bool);
316 y.float_array_value (),
318 match_idx, match_bool);
323 match_idx, match_bool);
332 str_y = y.cellstr_value ();
334 str_y(0) = y.string_value ();
346 match.xelem (i) = j != 0 && str_y(i) == str_table(j-1);
359 ridx.xelem (i) = (j != 0 && str_y(i) == str_table(j-1)) ? j