From 6bff4f32e5cbe9f7e51837f392a2d0bf0d5b721d Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Mon, 30 Jul 2001 19:09:29 +0000 Subject: [PATCH] - moved is_of_type and friend macros into utils.h so they can be phased out in one of the next releases. - rewrote the foo_evalf() functions without TYPECHECK macros. (Since they were not flexible enough and some functions need more flexibility than can be provided by such macros. They are evil anyways.) - marked the TYPECHECK macros as evil^H^H^H^Hdeprecated. - implemented a more flexible scheme for some foo_evalf() functions, notably zeta(3.0) eval's to a float now while zeta(3) doesn't eval, just as is usual for all the trigonometric functions. - this day is very hot. --- ginac/basic.h | 15 ----- ginac/expair.h | 3 +- ginac/function.pl | 5 +- ginac/idx.h | 9 +-- ginac/inifcns.cpp | 31 +++++---- ginac/inifcns_gamma.cpp | 59 +++++++++-------- ginac/inifcns_trans.cpp | 136 ++++++++++++++++++---------------------- ginac/inifcns_zeta.cpp | 17 +++-- ginac/input_lexer.ll | 9 +-- ginac/numeric.cpp | 25 ++------ ginac/utils.h | 20 ++++++ 11 files changed, 158 insertions(+), 171 deletions(-) diff --git a/ginac/basic.h b/ginac/basic.h index 28568c56..77134bd6 100644 --- a/ginac/basic.h +++ b/ginac/basic.h @@ -175,21 +175,6 @@ private: extern int max_recursion_level; -// Obsolete convenience macros. To be phased out soon! -// Use the inlined template functions below instead of these macros. - -#define is_of_type(OBJ,TYPE) \ - (dynamic_cast(&OBJ)!=0) - -#define is_exactly_of_type(OBJ,TYPE) \ - ((OBJ).tinfo()==GiNaC::TINFO_##TYPE) - -#define is_ex_of_type(OBJ,TYPE) \ - (dynamic_cast((OBJ).bp)!=0) - -#define is_ex_exactly_of_type(OBJ,TYPE) \ - ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE) - // convenience type checker template functions /** Check if obj is a T, including base classes. */ diff --git a/ginac/expair.h b/ginac/expair.h index a2852958..d7a76ca1 100644 --- a/ginac/expair.h +++ b/ginac/expair.h @@ -94,8 +94,7 @@ public: bool is_canonical_numeric(void) const { GINAC_ASSERT(is_exactly_a(coeff)); - return (is_ex_exactly_of_type(rest,numeric) && - (coeff.is_equal(1))); + return (is_exactly_a(rest) && (coeff.is_equal(1))); } /** Swap contents with other expair. */ diff --git a/ginac/function.pl b/ginac/function.pl index 258f4a07..26f37afd 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -201,6 +201,9 @@ $declare_function_macro const unsigned function_index_##NAME= \\ GiNaC::function::register_new(GiNaC::function_options(#NAME).OPT); +// The TYPECHECK-macros were used inside the _evalf() functions. They are +// considered obsolete now: (FIXME: remove them) + #define BEGIN_TYPECHECK \\ bool automatic_typecheck=true; @@ -376,7 +379,7 @@ template<> inline bool is_exactly_a(const basic & obj) } #define is_ex_the_function(OBJ, FUNCNAME) \\ - (is_ex_exactly_of_type(OBJ, function) && static_cast(OBJ.bp)->get_serial() == function_index_##FUNCNAME) + (is_exactly_a(OBJ) && static_cast(OBJ.bp)->get_serial() == function_index_##FUNCNAME) } // namespace GiNaC diff --git a/ginac/idx.h b/ginac/idx.h index c2ac9721..fd1ed47d 100644 --- a/ginac/idx.h +++ b/ginac/idx.h @@ -24,6 +24,7 @@ #define __GINAC_IDX_H__ #include "ex.h" +#include "numeric.h" namespace GiNaC { @@ -70,19 +71,19 @@ public: ex get_value(void) const {return value;} /** Check whether the index is numeric. */ - bool is_numeric(void) const {return is_ex_exactly_of_type(value, numeric);} + bool is_numeric(void) const {return is_exactly_a(value);} /** Check whether the index is symbolic. */ - bool is_symbolic(void) const {return !is_ex_exactly_of_type(value, numeric);} + bool is_symbolic(void) const {return !is_exactly_a(value);} /** Get dimension of index space. */ ex get_dim(void) const {return dim;} /** Check whether the dimension is numeric. */ - bool is_dim_numeric(void) const {return is_ex_exactly_of_type(dim, numeric);} + bool is_dim_numeric(void) const {return is_exactly_a(dim);} /** Check whether the dimension is symbolic. */ - bool is_dim_symbolic(void) const {return !is_ex_exactly_of_type(dim, numeric);} + bool is_dim_symbolic(void) const {return !is_exactly_a(dim);} protected: ex value; /**< Expression that constitutes the index (numeric or symbolic name) */ diff --git a/ginac/inifcns.cpp b/ginac/inifcns.cpp index c18f4c63..3258182e 100644 --- a/ginac/inifcns.cpp +++ b/ginac/inifcns.cpp @@ -44,11 +44,10 @@ namespace GiNaC { static ex abs_evalf(const ex & arg) { - BEGIN_TYPECHECK - TYPECHECK(arg,numeric) - END_TYPECHECK(abs(arg)) + if (is_exactly_a(arg)) + return abs(ex_to(arg)); - return abs(ex_to(arg)); + return abs(arg).hold(); } static ex abs_eval(const ex & arg) @@ -69,11 +68,10 @@ REGISTER_FUNCTION(abs, eval_func(abs_eval). static ex csgn_evalf(const ex & arg) { - BEGIN_TYPECHECK - TYPECHECK(arg,numeric) - END_TYPECHECK(csgn(arg)) + if (is_exactly_a(arg)) + return csgn(ex_to(arg)); - return csgn(ex_to(arg)); + return csgn(arg).hold(); } static ex csgn_eval(const ex & arg) @@ -198,7 +196,7 @@ static ex eta_series(const ex & x, const ex & y, REGISTER_FUNCTION(eta, eval_func(eta_eval). evalf_func(eta_evalf). - series_func(eta_series). + series_func(eta_series). latex_name("\\eta"). set_symmetry(sy_symm(0, 1))); @@ -209,11 +207,10 @@ REGISTER_FUNCTION(eta, eval_func(eta_eval). static ex Li2_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(Li2(x)) + if (is_exactly_a(x)) + return Li2(ex_to(x)); - return Li2(ex_to(x)); // -> numeric Li2(numeric) + return Li2(x).hold(); } static ex Li2_eval(const ex & x) @@ -239,7 +236,7 @@ static ex Li2_eval(const ex & x) return power(Pi,_ex2())/_ex_48() - Catalan*I; // Li2(float) if (!x.info(info_flags::crational)) - return Li2_evalf(x); + return Li2(ex_to(x)); } return Li2(x).hold(); @@ -250,7 +247,7 @@ static ex Li2_deriv(const ex & x, unsigned deriv_param) GINAC_ASSERT(deriv_param==0); // d/dx Li2(x) -> -log(1-x)/x - return -log(1-x)/x; + return -log(_ex1()-x)/x; } static ex Li2_series(const ex &x, const relational &rel, int order, unsigned options) @@ -293,7 +290,7 @@ static ex Li2_series(const ex &x, const relational &rel, int order, unsigned opt // obsolete! } // second special case: x==1 (branch point) - if (x_pt == _ex1()) { + if (x_pt.is_equal(_ex1())) { // method: // construct series manually in a dummy symbol s const symbol s; @@ -501,7 +498,7 @@ ex lsolve(const ex &eqns, const ex &symbols) // Probably singular matrix or otherwise overdetermined system: // It is consistent to return an empty list return lst(); - } + } GINAC_ASSERT(solution.cols()==1); GINAC_ASSERT(solution.rows()==symbols.nops()); diff --git a/ginac/inifcns_gamma.cpp b/ginac/inifcns_gamma.cpp index 4377efde..9c1da651 100644 --- a/ginac/inifcns_gamma.cpp +++ b/ginac/inifcns_gamma.cpp @@ -42,11 +42,13 @@ namespace GiNaC { static ex lgamma_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(lgamma(x)) + if (is_exactly_a(x)) { + try { + return lgamma(ex_to(x)); + } catch (const dunno &e) { } + } - return lgamma(ex_to(x)); + return lgamma(x).hold(); } @@ -120,11 +122,13 @@ REGISTER_FUNCTION(lgamma, eval_func(lgamma_eval). static ex tgamma_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(tgamma(x)) + if (is_exactly_a(x)) { + try { + return tgamma(ex_to(x)); + } catch (const dunno &e) { } + } - return tgamma(ex_to(x)); + return tgamma(x).hold(); } @@ -214,12 +218,13 @@ REGISTER_FUNCTION(tgamma, eval_func(tgamma_eval). static ex beta_evalf(const ex & x, const ex & y) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - TYPECHECK(y,numeric) - END_TYPECHECK(beta(x,y)) + if (is_exactly_a(x) && is_exactly_a(y)) { + try { + return tgamma(ex_to(x))*tgamma(ex_to(y))/tgamma(ex_to(x+y)); + } catch (const dunno &e) { } + } - return tgamma(ex_to(x))*tgamma(ex_to(y))/tgamma(ex_to(x+y)); + return beta(x,y).hold(); } @@ -249,11 +254,10 @@ static ex beta_eval(const ex & x, const ex & y) } // no problem in numerator, but denominator has pole: if ((nx+ny).is_real() && - (nx+ny).is_integer() && - !(nx+ny).is_positive()) + (nx+ny).is_integer() && + !(nx+ny).is_positive()) return _ex0(); - // everything is ok: - return tgamma(x)*tgamma(y)/tgamma(x+y); + // beta_evalf should be called here once it becomes available } return beta(x,y).hold(); @@ -327,11 +331,13 @@ REGISTER_FUNCTION(beta, eval_func(beta_eval). static ex psi1_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(psi(x)) + if (is_exactly_a(x)) { + try { + return psi(ex_to(x)); + } catch (const dunno &e) { } + } - return psi(ex_to(x)); + return psi(x).hold(); } /** Evaluation of digamma-function psi(x). @@ -426,12 +432,13 @@ const unsigned function_index_psi1 = static ex psi2_evalf(const ex & n, const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(n,numeric) - TYPECHECK(x,numeric) - END_TYPECHECK(psi(n,x)) + if (is_exactly_a(n) && is_exactly_a(x)) { + try { + return psi(ex_to(n),ex_to(x)); + } catch (const dunno &e) { } + } - return psi(ex_to(n), ex_to(x)); + return psi(n,x).hold(); } /** Evaluation of polygamma-function psi(n,x). diff --git a/ginac/inifcns_trans.cpp b/ginac/inifcns_trans.cpp index 150e3428..a626ce1c 100644 --- a/ginac/inifcns_trans.cpp +++ b/ginac/inifcns_trans.cpp @@ -42,11 +42,10 @@ namespace GiNaC { static ex exp_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(exp(x)) + if (is_exactly_a(x)) + return exp(ex_to(x)); - return exp(ex_to(x)); // -> numeric exp(numeric) + return exp(x).hold(); } static ex exp_eval(const ex & x) @@ -74,7 +73,7 @@ static ex exp_eval(const ex & x) // exp(float) if (x.info(info_flags::numeric) && !x.info(info_flags::crational)) - return exp_evalf(x); + return exp(ex_to(x)); return exp(x).hold(); } @@ -98,11 +97,10 @@ REGISTER_FUNCTION(exp, eval_func(exp_eval). static ex log_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(log(x)) + if (is_exactly_a(x)) + return log(ex_to(x)); - return log(ex_to(x)); // -> numeric log(numeric) + return log(x).hold(); } static ex log_eval(const ex & x) @@ -120,7 +118,7 @@ static ex log_eval(const ex & x) return (Pi*I*_num_1_2()); // log(float) if (!x.info(info_flags::crational)) - return log_evalf(x); + return log(ex_to(x)); } // log(exp(t)) -> t (if -Pi < t.imag() <= Pi): if (is_ex_the_function(x, exp)) { @@ -220,11 +218,10 @@ REGISTER_FUNCTION(log, eval_func(log_eval). static ex sin_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(sin(x)) + if (is_exactly_a(x)) + return sin(ex_to(x)); - return sin(ex_to(x)); // -> numeric sin(numeric) + return sin(x).hold(); } static ex sin_eval(const ex & x) @@ -278,7 +275,7 @@ static ex sin_eval(const ex & x) // sin(float) -> float if (x.info(info_flags::numeric) && !x.info(info_flags::crational)) - return sin_evalf(x); + return sin(ex_to(x)); return sin(x).hold(); } @@ -302,11 +299,10 @@ REGISTER_FUNCTION(sin, eval_func(sin_eval). static ex cos_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(cos(x)) + if (is_exactly_a(x)) + return cos(ex_to(x)); - return cos(ex_to(x)); // -> numeric cos(numeric) + return cos(x).hold(); } static ex cos_eval(const ex & x) @@ -360,7 +356,7 @@ static ex cos_eval(const ex & x) // cos(float) -> float if (x.info(info_flags::numeric) && !x.info(info_flags::crational)) - return cos_evalf(x); + return cos(ex_to(x)); return cos(x).hold(); } @@ -384,11 +380,10 @@ REGISTER_FUNCTION(cos, eval_func(cos_eval). static ex tan_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(tan(x)) // -> numeric tan(numeric) + if (is_exactly_a(x)) + return tan(ex_to(x)); - return tan(ex_to(x)); + return tan(x).hold(); } static ex tan_eval(const ex & x) @@ -438,7 +433,7 @@ static ex tan_eval(const ex & x) // tan(float) -> float if (x.info(info_flags::numeric) && !x.info(info_flags::crational)) { - return tan_evalf(x); + return tan(ex_to(x)); } return tan(x).hold(); @@ -480,11 +475,10 @@ REGISTER_FUNCTION(tan, eval_func(tan_eval). static ex asin_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(asin(x)) + if (is_exactly_a(x)) + return asin(ex_to(x)); - return asin(ex_to(x)); // -> numeric asin(numeric) + return asin(x).hold(); } static ex asin_eval(const ex & x) @@ -507,7 +501,7 @@ static ex asin_eval(const ex & x) return _num_1_2()*Pi; // asin(float) -> float if (!x.info(info_flags::crational)) - return asin_evalf(x); + return asin(ex_to(x)); } return asin(x).hold(); @@ -532,11 +526,10 @@ REGISTER_FUNCTION(asin, eval_func(asin_eval). static ex acos_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(acos(x)) + if (is_exactly_a(x)) + return acos(ex_to(x)); - return acos(ex_to(x)); // -> numeric acos(numeric) + return acos(x).hold(); } static ex acos_eval(const ex & x) @@ -559,7 +552,7 @@ static ex acos_eval(const ex & x) return Pi; // acos(float) -> float if (!x.info(info_flags::crational)) - return acos_evalf(x); + return acos(ex_to(x)); } return acos(x).hold(); @@ -584,11 +577,10 @@ REGISTER_FUNCTION(acos, eval_func(acos_eval). static ex atan_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(atan(x)) + if (is_exactly_a(x)) + return atan(ex_to(x)); - return atan(ex_to(x)); // -> numeric atan(numeric) + return atan(x).hold(); } static ex atan_eval(const ex & x) @@ -607,7 +599,7 @@ static ex atan_eval(const ex & x) throw (pole_error("atan_eval(): logarithmic pole",0)); // atan(float) -> float if (!x.info(info_flags::crational)) - return atan_evalf(x); + return atan(ex_to(x)); } return atan(x).hold(); @@ -674,14 +666,12 @@ REGISTER_FUNCTION(atan, eval_func(atan_eval). // inverse tangent (atan2(y,x)) ////////// -static ex atan2_evalf(const ex & y, const ex & x) +static ex atan2_evalf(const ex &y, const ex &x) { - BEGIN_TYPECHECK - TYPECHECK(y,numeric) - TYPECHECK(x,numeric) - END_TYPECHECK(atan2(y,x)) + if (is_exactly_a(y) && is_exactly_a(x)) + return atan2(ex_to(y), ex_to(x)); - return atan(ex_to(y),ex_to(x)); // -> numeric atan(numeric) + return atan2(y, x).hold(); } static ex atan2_eval(const ex & y, const ex & x) @@ -716,11 +706,10 @@ REGISTER_FUNCTION(atan2, eval_func(atan2_eval). static ex sinh_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(sinh(x)) + if (is_exactly_a(x)) + return sinh(ex_to(x)); - return sinh(ex_to(x)); // -> numeric sinh(numeric) + return sinh(x).hold(); } static ex sinh_eval(const ex & x) @@ -729,7 +718,7 @@ static ex sinh_eval(const ex & x) if (x.is_zero()) // sinh(0) -> 0 return _ex0(); if (!x.info(info_flags::crational)) // sinh(float) -> float - return sinh_evalf(x); + return sinh(ex_to(x)); } if ((x/Pi).info(info_flags::numeric) && @@ -771,11 +760,10 @@ REGISTER_FUNCTION(sinh, eval_func(sinh_eval). static ex cosh_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(cosh(x)) + if (is_exactly_a(x)) + return cosh(ex_to(x)); - return cosh(ex_to(x)); // -> numeric cosh(numeric) + return cosh(x).hold(); } static ex cosh_eval(const ex & x) @@ -784,7 +772,7 @@ static ex cosh_eval(const ex & x) if (x.is_zero()) // cosh(0) -> 1 return _ex1(); if (!x.info(info_flags::crational)) // cosh(float) -> float - return cosh_evalf(x); + return cosh(ex_to(x)); } if ((x/Pi).info(info_flags::numeric) && @@ -826,11 +814,10 @@ REGISTER_FUNCTION(cosh, eval_func(cosh_eval). static ex tanh_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(tanh(x)) + if (is_exactly_a(x)) + return tanh(ex_to(x)); - return tanh(ex_to(x)); // -> numeric tanh(numeric) + return tanh(x).hold(); } static ex tanh_eval(const ex & x) @@ -839,7 +826,7 @@ static ex tanh_eval(const ex & x) if (x.is_zero()) // tanh(0) -> 0 return _ex0(); if (!x.info(info_flags::crational)) // tanh(float) -> float - return tanh_evalf(x); + return tanh(ex_to(x)); } if ((x/Pi).info(info_flags::numeric) && @@ -898,11 +885,10 @@ REGISTER_FUNCTION(tanh, eval_func(tanh_eval). static ex asinh_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(asinh(x)) + if (is_exactly_a(x)) + return asinh(ex_to(x)); - return asinh(ex_to(x)); // -> numeric asinh(numeric) + return asinh(x).hold(); } static ex asinh_eval(const ex & x) @@ -913,7 +899,7 @@ static ex asinh_eval(const ex & x) return _ex0(); // asinh(float) -> float if (!x.info(info_flags::crational)) - return asinh_evalf(x); + return asinh(ex_to(x)); } return asinh(x).hold(); @@ -937,11 +923,10 @@ REGISTER_FUNCTION(asinh, eval_func(asinh_eval). static ex acosh_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(acosh(x)) + if (is_exactly_a(x)) + return acosh(ex_to(x)); - return acosh(ex_to(x)); // -> numeric acosh(numeric) + return acosh(x).hold(); } static ex acosh_eval(const ex & x) @@ -958,7 +943,7 @@ static ex acosh_eval(const ex & x) return Pi*I; // acosh(float) -> float if (!x.info(info_flags::crational)) - return acosh_evalf(x); + return acosh(ex_to(x)); } return acosh(x).hold(); @@ -982,11 +967,10 @@ REGISTER_FUNCTION(acosh, eval_func(acosh_eval). static ex atanh_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(atanh(x)) + if (is_exactly_a(x)) + return atanh(ex_to(x)); - return atanh(ex_to(x)); // -> numeric atanh(numeric) + return atanh(x).hold(); } static ex atanh_eval(const ex & x) @@ -1000,7 +984,7 @@ static ex atanh_eval(const ex & x) throw (pole_error("atanh_eval(): logarithmic pole",0)); // atanh(float) -> float if (!x.info(info_flags::crational)) - return atanh_evalf(x); + return atanh(ex_to(x)); } return atanh(x).hold(); diff --git a/ginac/inifcns_zeta.cpp b/ginac/inifcns_zeta.cpp index 9cd0961a..53eba05b 100644 --- a/ginac/inifcns_zeta.cpp +++ b/ginac/inifcns_zeta.cpp @@ -38,11 +38,13 @@ namespace GiNaC { static ex zeta1_evalf(const ex & x) { - BEGIN_TYPECHECK - TYPECHECK(x,numeric) - END_TYPECHECK(zeta(x)) - - return zeta(ex_to(x)); + if (is_exactly_a(x)) { + try { + return zeta(ex_to(x)); + } catch (const dunno &e) { } + } + + return zeta(x).hold(); } static ex zeta1_eval(const ex & x) @@ -52,7 +54,7 @@ static ex zeta1_eval(const ex & x) // trap integer arguments: if (y.is_integer()) { if (y.is_zero()) - return -_ex1_2(); + return _ex_1_2(); if (x.is_equal(_ex1())) throw(std::domain_error("zeta(1): infinity")); if (x.info(info_flags::posint)) { @@ -67,6 +69,9 @@ static ex zeta1_eval(const ex & x) return _num0(); } } + // zeta(float) + if (x.info(info_flags::numeric) && !x.info(info_flags::crational)) + return zeta1_evalf(x); } return zeta(x).hold(); } diff --git a/ginac/input_lexer.ll b/ginac/input_lexer.ll index f39de456..e4757b9d 100644 --- a/ginac/input_lexer.ll +++ b/ginac/input_lexer.ll @@ -38,6 +38,7 @@ #include "fail.h" #include "numeric.h" #include "symbol.h" +#include "lst.h" using namespace GiNaC; namespace GiNaC { @@ -169,18 +170,18 @@ void set_lexer_string(const std::string &s) void set_lexer_symbols(ex l) { syms.clear(); - if (!is_ex_exactly_of_type(l, lst)) + if (!is_exactly_a(l)) return; for (unsigned i=0; i(l.op(i))) + syms[ex_to(l.op(i)).get_name()] = sym_def(l.op(i), true); } } // Check whether symbol was predefined bool is_lexer_symbol_predefined(const ex &s) { - sym_tab::const_iterator i = syms.find(ex_to_symbol(s).get_name()); + sym_tab::const_iterator i = syms.find(ex_to(s).get_name()); if (i == syms.end()) return false; else diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index ba9b8210..0303b6d7 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -1432,10 +1432,7 @@ const numeric zeta(const numeric &x) if (cln::zerop(x.to_cl_N()-aux)) return cln::zeta(aux); } - std::clog << "zeta(" << x - << "): Does anybody know a good way to calculate this numerically?" - << std::endl; - return numeric(0); + throw dunno(); } @@ -1443,17 +1440,11 @@ const numeric zeta(const numeric &x) * This is only a stub! */ const numeric lgamma(const numeric &x) { - std::clog << "lgamma(" << x - << "): Does anybody know a good way to calculate this numerically?" - << std::endl; - return numeric(0); + throw dunno(); } const numeric tgamma(const numeric &x) { - std::clog << "tgamma(" << x - << "): Does anybody know a good way to calculate this numerically?" - << std::endl; - return numeric(0); + throw dunno(); } @@ -1461,10 +1452,7 @@ const numeric tgamma(const numeric &x) * This is only a stub! */ const numeric psi(const numeric &x) { - std::clog << "psi(" << x - << "): Does anybody know a good way to calculate this numerically?" - << std::endl; - return numeric(0); + throw dunno(); } @@ -1472,10 +1460,7 @@ const numeric psi(const numeric &x) * This is only a stub! */ const numeric psi(const numeric &n, const numeric &x) { - std::clog << "psi(" << n << "," << x - << "): Does anybody know a good way to calculate this numerically?" - << std::endl; - return numeric(0); + throw dunno(); } diff --git a/ginac/utils.h b/ginac/utils.h index 001f64f4..78334b17 100644 --- a/ginac/utils.h +++ b/ginac/utils.h @@ -36,6 +36,10 @@ namespace GiNaC { * to signal that ordinary Taylor expansion is safe. */ class do_taylor {}; +/** Exception class thrown by functions to signal unimplemented functionality + * so the expression may just be .hold() */ +class dunno {}; + /** Exception class thrown when a singularity is encountered. */ class pole_error : public std::domain_error { public: @@ -472,6 +476,22 @@ void classname::print(const print_context & c, unsigned level) const \ c.s << text; \ } +// Obsolete convenience macros. TO BE PHASED OUT SOON! +// Use the inlined template functions in basic.h instead. (FIXME: remove them) + +#define is_of_type(OBJ,TYPE) \ + (dynamic_cast(&OBJ)!=0) + +#define is_exactly_of_type(OBJ,TYPE) \ + ((OBJ).tinfo()==GiNaC::TINFO_##TYPE) + +#define is_ex_of_type(OBJ,TYPE) \ + (dynamic_cast((OBJ).bp)!=0) + +#define is_ex_exactly_of_type(OBJ,TYPE) \ + ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE) + } // namespace GiNaC + #endif // ndef __GINAC_UTILS_H__ -- 2.44.0