# HG changeset patch # User jwe # Date 830505368 0 # Node ID 4dcc8b77e84aea3ee21144912ba9529ba96325b9 # Parent c5b4b6d5174068a4877fd743b0b33b5fbb342c66 [project @ 1996-04-26 07:55:54 by jwe] diff --git a/src/defun.h b/src/defun.h --- a/src/defun.h +++ b/src/defun.h @@ -112,15 +112,9 @@ // // name is the name of the function, unquoqted. // -// can_ret_cmplx_for_real is a flag that says whether this function -// can create a complex number given a real-valued argument -// (e.g., sqrt (-1)). -// -// lo is the lower bound of the range for which real arguments can -// become complex. (e.g., lo == -Inf for sqrt). -// -// hi is the upper bound of the range for which real arguments can -// become complex. (e.g., hi == 0 for sqrt). +// ch_map is a pointer to a function that should be called for +// integer arguments that are expected to creat integer results. +// (It's a kluge to handle character mappers like isalpha.) // // d_d_map is a pointer to a function that should be called for real // arguments that are expected to create real results. @@ -131,15 +125,26 @@ // c_c_map is a pointer to a function that should be called for // complex arguments that are expected to create complex results. // +// lo is the lower bound of the range for which real arguments can +// become complex. (e.g., lo == -Inf for sqrt). +// +// hi is the upper bound of the range for which real arguments can +// become complex. (e.g., hi == 0 for sqrt). +// +// can_ret_cmplx_for_real is a flag that says whether this function +// can create a complex number given a real-valued argument +// (e.g., sqrt (-1)). +// // doc is the simple help text for the function. -#define DEFUN_MAPPER(name, can_ret_cmplx_for_real, lo, hi, \ - d_d_map, d_c_map, c_c_map, doc) \ +#define DEFUN_MAPPER(name, ch_map, d_d_map, d_c_map, c_c_map, \ + lo, hi, can_ret_cmplx_for_real, doc) \ do \ { \ - builtin_mapper_function S ## name (#name, can_ret_cmplx_for_real, \ - lo, hi, d_d_map, d_c_map, \ - c_c_map, doc); \ + builtin_mapper_function S ## name (ch_map, d_d_map, \ + d_c_map, c_c_map, lo, hi, \ + can_ret_cmplx_for_real, \ + #name, doc); \ install_builtin_mapper (S ## name); \ } \ while (0) diff --git a/src/mappers.cc b/src/mappers.cc --- a/src/mappers.cc +++ b/src/mappers.cc @@ -24,6 +24,7 @@ #include #endif +#include #include #include "oct-cmplx.h" @@ -335,106 +336,142 @@ void install_mapper_functions (void) { - DEFUN_MAPPER (abs, 0, 0.0, 0.0, fabs, abs, 0, + DEFUN_MAPPER (abs, 0, fabs, abs, 0, 0.0, 0.0, 0, "abs (X): compute abs (X) for each element of X"); - DEFUN_MAPPER (acos, 1, -1.0, 1.0, acos, 0, acos, + DEFUN_MAPPER (acos, 0, acos, 0, acos, -1.0, 1.0, 1, "acos (X): compute acos (X) for each element of X"); - DEFUN_MAPPER (acosh, 1, 1.0, DBL_MAX, acosh, 0, acosh, + DEFUN_MAPPER (acosh, 0, acosh, 0, acosh, 1.0, DBL_MAX, 1, "acosh (X): compute acosh (X) for each element of X"); - DEFUN_MAPPER (angle, 0, 0.0, 0.0, arg, arg, 0, + DEFUN_MAPPER (angle, 0, arg, arg, 0, 0.0, 0.0, 0, "angle (X): compute arg (X) for each element of X"); - DEFUN_MAPPER (arg, 0, 0.0, 0.0, arg, arg, 0, + DEFUN_MAPPER (arg, 0, arg, arg, 0, 0.0, 0.0, 0, "arg (X): compute arg (X) for each element of X"); - DEFUN_MAPPER (asin, 1, -1.0, 1.0, asin, 0, asin, + DEFUN_MAPPER (asin, 0, asin, 0, asin, -1.0, 1.0, 1, "asin (X): compute asin (X) for each element of X"); - DEFUN_MAPPER (asinh, 0, 0.0, 0.0, asinh, 0, asinh, + DEFUN_MAPPER (asinh, 0, asinh, 0, asinh, 0.0, 0.0, 0, "asinh (X): compute asinh (X) for each element of X"); - DEFUN_MAPPER (atan, 0, 0.0, 0.0, atan, 0, atan, + DEFUN_MAPPER (atan, 0, atan, 0, atan, 0.0, 0.0, 0, "atan (X): compute atan (X) for each element of X"); - DEFUN_MAPPER (atanh, 1, -1.0, 1.0, atanh, 0, atanh, + DEFUN_MAPPER (atanh, 0, atanh, 0, atanh, -1.0, 1.0, 1, "atanh (X): compute atanh (X) for each element of X"); - DEFUN_MAPPER (ceil, 0, 0.0, 0.0, ceil, 0, ceil, + DEFUN_MAPPER (ceil, 0, ceil, 0, ceil, 0.0, 0.0, 0, "ceil (X): round elements of X toward +Inf"); - DEFUN_MAPPER (conj, 0, 0.0, 0.0, conj, 0, conj, + DEFUN_MAPPER (conj, 0, conj, 0, conj, 0.0, 0.0, 0, "conj (X): compute complex conjugate for each element of X"); - DEFUN_MAPPER (cos, 0, 0.0, 0.0, cos, 0, cos, + DEFUN_MAPPER (cos, 0, cos, 0, cos, 0.0, 0.0, 0, "cos (X): compute cos (X) for each element of X"); - DEFUN_MAPPER (cosh, 0, 0.0, 0.0, cosh, 0, cosh, + DEFUN_MAPPER (cosh, 0, cosh, 0, cosh, 0.0, 0.0, 0, "cosh (X): compute cosh (X) for each element of X"); - DEFUN_MAPPER (erf, 0, 0.0, 0.0, xerf, 0, 0, + DEFUN_MAPPER (erf, 0, xerf, 0, 0, 0.0, 0.0, 0, "erf (X): compute erf (X) for each element of X"); - DEFUN_MAPPER (erfc, 0, 0.0, 0.0, xerfc, 0, 0, + DEFUN_MAPPER (erfc, 0, xerfc, 0, 0, 0.0, 0.0, 0, "erfc (X): compute erfc (X) for each element of X"); - DEFUN_MAPPER (exp, 0, 0.0, 0.0, exp, 0, exp, + DEFUN_MAPPER (exp, 0, exp, 0, exp, 0.0, 0.0, 0, "exp (X): compute exp (X) for each element of X"); - DEFUN_MAPPER (finite, 0, 0.0, 0.0, xfinite, xfinite, 0, + DEFUN_MAPPER (finite, 0, xfinite, xfinite, 0, 0.0, 0.0, 0, "finite (X): return 1 for finite elements of X"); - DEFUN_MAPPER (fix, 0, 0.0, 0.0, fix, 0, fix, + DEFUN_MAPPER (fix, 0, fix, 0, fix, 0.0, 0.0, 0, "fix (X): round elements of X toward zero"); - DEFUN_MAPPER (floor, 0, 0.0, 0.0, floor, 0, floor, + DEFUN_MAPPER (floor, 0, floor, 0, floor, 0.0, 0.0, 0, "floor (X): round elements of X toward -Inf"); - DEFUN_MAPPER (gamma, 0, 0.0, 0.0, xgamma, 0, 0, + DEFUN_MAPPER (gamma, 0, xgamma, 0, 0, 0.0, 0.0, 0, "gamma (X): compute gamma (X) for each element of X"); - DEFUN_MAPPER (isinf, 0, 0.0, 0.0, xisinf, xisinf, 0, + DEFUN_MAPPER (imag, 0, imag, imag, 0, 0.0, 0.0, 0, + "imag (X): return imaginary part for each elements of X"); + + DEFUN_MAPPER (isalnum, isalnum, 0, 0, 0, 0.0, 0.0, 0, + "isalnum (X): "); + + DEFUN_MAPPER (isalpha, isalpha, 0, 0, 0, 0.0, 0.0, 0, + "isalpha (X): "); + + DEFUN_MAPPER (isascii, isascii, 0, 0, 0, 0.0, 0.0, 0, + "isascii (X): "); + + DEFUN_MAPPER (iscntrl, iscntrl, 0, 0, 0, 0.0, 0.0, 0, + "iscntrl (X): "); + + DEFUN_MAPPER (isdigit, isdigit, 0, 0, 0, 0.0, 0.0, 0, + "isdigit (X): "); + + DEFUN_MAPPER (isinf, 0, xisinf, xisinf, 0, 0.0, 0.0, 0, "isinf (X): return 1 for elements of X infinite"); - DEFUN_MAPPER (imag, 0, 0.0, 0.0, imag, imag, 0, - "imag (X): return imaginary part for each elements of X"); + DEFUN_MAPPER (isgraph, isgraph, 0, 0, 0, 0.0, 0.0, 0, + "isgraph (X): "); - DEFUN_MAPPER (isnan, 0, 0.0, 0.0, xisnan, xisnan, 0, + DEFUN_MAPPER (islower, islower, 0, 0, 0, 0.0, 0.0, 0, + "islower (X): "); + + DEFUN_MAPPER (isnan, 0, xisnan, xisnan, 0, 0.0, 0.0, 0, "isnan (X): return 1 where elements of X are NaNs"); - DEFUN_MAPPER (lgamma, 0, 0.0, 0.0, xlgamma, 0, 0, + DEFUN_MAPPER (isprint, isprint, 0, 0, 0, 0.0, 0.0, 0, + "isprint (X): "); + + DEFUN_MAPPER (ispunct, ispunct, 0, 0, 0, 0.0, 0.0, 0, + "ispunct (X): "); + + DEFUN_MAPPER (isspace, isspace, 0, 0, 0, 0.0, 0.0, 0, + "isspace (X): "); + + DEFUN_MAPPER (isupper, isupper, 0, 0, 0, 0.0, 0.0, 0, + "isupper (X): "); + + DEFUN_MAPPER (isxdigit, isxdigit, 0, 0, 0, 0.0, 0.0, 0, + "isxdigit (X): "); + + DEFUN_MAPPER (lgamma, 0, xlgamma, 0, 0, 0.0, 0.0, 0, "lgamma (X): compute log gamma (X) for each element of X"); - DEFUN_MAPPER (log, 1, 0.0, DBL_MAX, log, 0, log, + DEFUN_MAPPER (log, 0, log, 0, log, 0.0, DBL_MAX, 1, "log (X): compute log (X) for each element of X"); - DEFUN_MAPPER (log10, 1, 0.0, DBL_MAX, log10, 0, log10, + DEFUN_MAPPER (log10, 0, log10, 0, log10, 0.0, DBL_MAX, 1, "log10 (X): compute log10 (X) for each element of X"); - DEFUN_MAPPER (real, 0, 0.0, 0.0, real, real, 0, + DEFUN_MAPPER (real, 0, real, real, 0, 0.0, 0.0, 0, "real (X): return real part for each element of X"); - DEFUN_MAPPER (round, 0, 0.0, 0.0, round, 0, round, + DEFUN_MAPPER (round, 0, round, 0, round, 0.0, 0.0, 0, "round (X): round elements of X to nearest integer"); - DEFUN_MAPPER (sign, 0, 0.0, 0.0, signum, 0, signum, + DEFUN_MAPPER (sign, 0, signum, 0, signum, 0.0, 0.0, 0, "sign (X): apply signum function to elements of X"); - DEFUN_MAPPER (sin, 0, 0.0, 0.0, sin, 0, sin, + DEFUN_MAPPER (sin, 0, sin, 0, sin, 0.0, 0.0, 0, "sin (X): compute sin (X) for each element of X"); - DEFUN_MAPPER (sinh, 0, 0.0, 0.0, sinh, 0, sinh, + DEFUN_MAPPER (sinh, 0, sinh, 0, sinh, 0.0, 0.0, 0, "sinh (X): compute sinh (X) for each element of X"); - DEFUN_MAPPER (sqrt, 1, 0.0, DBL_MAX, sqrt, 0, sqrt, + DEFUN_MAPPER (sqrt, 0, sqrt, 0, sqrt, 0.0, DBL_MAX, 1, "sqrt (X): compute sqrt (X) for each element of X"); - DEFUN_MAPPER (tan, 0, 0.0, 0.0, tan, 0, tan, + DEFUN_MAPPER (tan, 0, tan, 0, tan, 0.0, 0.0, 0, "tan (X): compute tan (X) for each element of X"); - DEFUN_MAPPER (tanh, 0, 0.0, 0.0, tanh, 0, tanh, + DEFUN_MAPPER (tanh, 0, tanh, 0, tanh, 0.0, 0.0, 0, "tanh (X): compute tanh (X) for each element of X"); DEFALIAS (gammaln, lgamma); diff --git a/src/mappers.h b/src/mappers.h --- a/src/mappers.h +++ b/src/mappers.h @@ -43,27 +43,43 @@ // If can_return_complex_for_real_arg is 0, lower_limit and // upper_limit are ignored. -struct Mapper_fcn -{ - ch_Mapper ch_mapper; - d_d_Mapper d_d_mapper; - d_c_Mapper d_c_mapper; - c_c_Mapper c_c_mapper; - double lower_limit; - double upper_limit; - int can_return_complex_for_real_arg; - string name; -}; - struct builtin_mapper_function { - builtin_mapper_function (ch_Mapper ch, d_d_Mapper dd, d_c_Mapper dc, - c_c_Mapper cc, double l, double u, - int cfr, const string n, const string& h) + builtin_mapper_function (ch_Mapper ch = 0, d_d_Mapper dd = 0, + d_c_Mapper dc = 0, c_c_Mapper cc = 0, + double l = 0.0, double u = 0.0, int cfr = 0, + const string n = string (), + const string& h = string ()) : ch_mapper (ch), d_d_mapper (dd), d_c_mapper (dc), c_c_mapper (cc), lower_limit (l), upper_limit (u), can_return_complex_for_real_arg (cfr), name (n), help_string (h) { } + builtin_mapper_function (const builtin_mapper_function& mf) + : ch_mapper (mf.ch_mapper), d_d_mapper (mf.d_d_mapper), + d_c_mapper (mf.d_c_mapper), c_c_mapper (mf.c_c_mapper), + lower_limit (mf.lower_limit), upper_limit (mf.upper_limit), + can_return_complex_for_real_arg (mf.can_return_complex_for_real_arg), + name (mf.name), help_string (mf.help_string) { } + + builtin_mapper_function& operator = (const builtin_mapper_function& mf) + { + if (&mf != this) + { + ch_mapper = mf.ch_mapper; + d_d_mapper = mf.d_d_mapper; + d_c_mapper = mf.d_c_mapper; + c_c_mapper = mf.c_c_mapper; + lower_limit = mf.lower_limit; + upper_limit = mf.upper_limit; + can_return_complex_for_real_arg = mf.can_return_complex_for_real_arg; + name = mf.name; + help_string = mf.help_string; + } + return *this; + } + + ~builtin_mapper_function (void) { } + ch_Mapper ch_mapper; d_d_Mapper d_d_mapper; d_c_Mapper d_c_mapper; diff --git a/src/pt-const.h b/src/pt-const.h --- a/src/pt-const.h +++ b/src/pt-const.h @@ -596,7 +596,7 @@ // class wants a certain kind of constant, he should simply ask for // it, and we should convert it if possible. - octave_value convert_to_str (void) + octave_value convert_to_str (void) const { return rep->convert_to_str (); } void convert_to_row_or_column_vector (void) diff --git a/src/pt-fvc.cc b/src/pt-fvc.cc --- a/src/pt-fvc.cc +++ b/src/pt-fvc.cc @@ -617,7 +617,8 @@ my_name = nm; } -tree_builtin::tree_builtin (builtin_mapper_function& m_fcn, const string &nm) +tree_builtin::tree_builtin (const builtin_mapper_function& m_fcn, + const string &nm) { mapper_fcn = m_fcn; is_mapper = 1; @@ -663,83 +664,115 @@ { octave_value retval; - if (arg.is_real_type ()) + if (m_fcn.ch_mapper) { - if (arg.is_scalar_type ()) + // XXX FIXME XXX -- this could be done in a better way... + + octave_value tmp = arg.convert_to_str (); + + if (! error_state) { - double d = arg.double_value (); + charMatrix chm = tmp.char_matrix_value (); - if (m_fcn.can_return_complex_for_real_arg - && (d < m_fcn.lower_limit || d > m_fcn.upper_limit)) + if (! error_state) { - if (m_fcn.c_c_mapper) - retval = m_fcn.c_c_mapper (Complex (d)); - else - error ("%s: unable to handle real arguments", - m_fcn.name.c_str ()); + int nr = chm.rows (); + int nc = chm.cols (); + + Matrix result (nr, nc); + + // islapha and friends can return any nonzero value to + // mean true. + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + result.elem (i, j) + = (*m_fcn.ch_mapper) (chm.elem (i, j)) ? 1 : 0; + + retval = result; } - else if (m_fcn.d_d_mapper) - retval = m_fcn.d_d_mapper (d); - else - error ("%s: unable to handle real arguments", - m_fcn.name.c_str ()); } - else + } + else + { + if (arg.is_real_type ()) { - Matrix m = arg.matrix_value (); + if (arg.is_scalar_type ()) + { + double d = arg.double_value (); - if (error_state) - return retval; - - if (m_fcn.can_return_complex_for_real_arg - && (any_element_less_than (m, m_fcn.lower_limit) - || any_element_greater_than (m, m_fcn.upper_limit))) - { - if (m_fcn.c_c_mapper) - retval = map (m_fcn.c_c_mapper, ComplexMatrix (m)); + if (m_fcn.can_return_complex_for_real_arg + && (d < m_fcn.lower_limit || d > m_fcn.upper_limit)) + { + if (m_fcn.c_c_mapper) + retval = m_fcn.c_c_mapper (Complex (d)); + else + error ("%s: unable to handle real arguments", + m_fcn.name.c_str ()); + } + else if (m_fcn.d_d_mapper) + retval = m_fcn.d_d_mapper (d); else error ("%s: unable to handle real arguments", m_fcn.name.c_str ()); } - else if (m_fcn.d_d_mapper) - retval = map (m_fcn.d_d_mapper, m); else - error ("%s: unable to handle real arguments", - m_fcn.name.c_str ()); + { + Matrix m = arg.matrix_value (); + + if (error_state) + return retval; + + if (m_fcn.can_return_complex_for_real_arg + && (any_element_less_than (m, m_fcn.lower_limit) + || any_element_greater_than (m, m_fcn.upper_limit))) + { + if (m_fcn.c_c_mapper) + retval = map (m_fcn.c_c_mapper, ComplexMatrix (m)); + else + error ("%s: unable to handle real arguments", + m_fcn.name.c_str ()); + } + else if (m_fcn.d_d_mapper) + retval = map (m_fcn.d_d_mapper, m); + else + error ("%s: unable to handle real arguments", + m_fcn.name.c_str ()); + } } - } - else if (arg.is_complex_type ()) - { - if (arg.is_scalar_type ()) + else if (arg.is_complex_type ()) { - Complex c = arg.complex_value (); + if (arg.is_scalar_type ()) + { + Complex c = arg.complex_value (); - if (m_fcn.d_c_mapper) - retval = m_fcn.d_c_mapper (c); - else if (m_fcn.c_c_mapper) - retval = m_fcn.c_c_mapper (c); + if (m_fcn.d_c_mapper) + retval = m_fcn.d_c_mapper (c); + else if (m_fcn.c_c_mapper) + retval = m_fcn.c_c_mapper (c); + else + error ("%s: unable to handle complex arguments", + m_fcn.name.c_str ()); + } else - error ("%s: unable to handle complex arguments", - m_fcn.name.c_str ()); + { + ComplexMatrix cm = arg.complex_matrix_value (); + + if (error_state) + return retval; + + if (m_fcn.d_c_mapper) + retval = map (m_fcn.d_c_mapper, cm); + else if (m_fcn.c_c_mapper) + retval = map (m_fcn.c_c_mapper, cm); + else + error ("%s: unable to handle complex arguments", + m_fcn.name.c_str ()); + } } else - { - ComplexMatrix cm = arg.complex_matrix_value (); - - if (error_state) - return retval; - - if (m_fcn.d_c_mapper) - retval = map (m_fcn.d_c_mapper, cm); - else if (m_fcn.c_c_mapper) - retval = map (m_fcn.c_c_mapper, cm); - else - error ("%s: unable to handle complex arguments", - m_fcn.name.c_str ()); - } + gripe_wrong_type_arg ("mapper", arg); } - else - gripe_wrong_type_arg ("mapper", arg); return retval; } diff --git a/src/pt-fvc.h b/src/pt-fvc.h --- a/src/pt-fvc.h +++ b/src/pt-fvc.h @@ -153,7 +153,8 @@ public: tree_builtin (const string& nm = string ()); - tree_builtin (builtin_mapper_function& m_fcn, const string& nm = string ()); + tree_builtin (const builtin_mapper_function& m_fcn, + const string& nm = string ()); tree_builtin (Octave_builtin_fcn f, const string& nm = string ()); diff --git a/src/variables.cc b/src/variables.cc --- a/src/variables.cc +++ b/src/variables.cc @@ -1387,17 +1387,7 @@ symbol_record *sym_rec = global_sym_tab->lookup (mf.name, 1); sym_rec->unprotect (); - Mapper_fcn mfcn; - - mfcn.name = mf.name; - mfcn.can_return_complex_for_real_arg = mf.can_return_complex_for_real_arg; - mfcn.lower_limit = mf.lower_limit; - mfcn.upper_limit = mf.upper_limit; - mfcn.d_d_mapper = mf.d_d_mapper; - mfcn.d_c_mapper = mf.d_c_mapper; - mfcn.c_c_mapper = mf.c_c_mapper; - - tree_builtin *def = new tree_builtin (mfcn, mf.name); + tree_builtin *def = new tree_builtin (mf, mf.name); sym_rec->define (def);