- moved is_of_type and friend macros into utils.h so they can be phased
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Mon, 30 Jul 2001 19:09:29 +0000 (19:09 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Mon, 30 Jul 2001 19:09:29 +0000 (19:09 +0000)
  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
ginac/expair.h
ginac/function.pl
ginac/idx.h
ginac/inifcns.cpp
ginac/inifcns_gamma.cpp
ginac/inifcns_trans.cpp
ginac/inifcns_zeta.cpp
ginac/input_lexer.ll
ginac/numeric.cpp
ginac/utils.h

index 28568c56025353be45b9b7d3cb5be1e0c39b7e36..77134bd612ca568fffec2438e50c2163da1af8cf 100644 (file)
@@ -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<const TYPE *>(&OBJ)!=0)
-
-#define is_exactly_of_type(OBJ,TYPE) \
-       ((OBJ).tinfo()==GiNaC::TINFO_##TYPE)
-
-#define is_ex_of_type(OBJ,TYPE) \
-       (dynamic_cast<const TYPE *>((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. */
index a285295899223a9268628cf639d9551ca01e238e..d7a76ca1574dc115e831492467748caf85152ab3 100644 (file)
@@ -94,8 +94,7 @@ public:
        bool is_canonical_numeric(void) const
        {
                GINAC_ASSERT(is_exactly_a<numeric>(coeff));
-               return (is_ex_exactly_of_type(rest,numeric) &&
-                       (coeff.is_equal(1)));
+               return (is_exactly_a<numeric>(rest) && (coeff.is_equal(1)));
        }
 
        /** Swap contents with other expair. */
index 258f4a07b82ea18fce25d639ea58317d68b1cbfe..26f37afdc29db6bd3e07cd6382bb51731749d79d 100755 (executable)
@@ -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<function>(const basic & obj)
 }
 
 #define is_ex_the_function(OBJ, FUNCNAME) \\
-       (is_ex_exactly_of_type(OBJ, function) && static_cast<GiNaC::function *>(OBJ.bp)->get_serial() == function_index_##FUNCNAME)
+       (is_exactly_a<function>(OBJ) && static_cast<GiNaC::function *>(OBJ.bp)->get_serial() == function_index_##FUNCNAME)
 
 } // namespace GiNaC
 
index c2ac972108ecf1c22e4402259a9ff5af4d783327..fd1ed47ddaac0e02427c276b028d839c953a6066 100644 (file)
@@ -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<numeric>(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<numeric>(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<numeric>(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<numeric>(dim);}
 
 protected:
        ex value; /**< Expression that constitutes the index (numeric or symbolic name) */
index c18f4c6385c8a3500dac0ca4700b88de2c64d4fa..3258182e3a65aeb163e0feb18fbdd785b263bfb7 100644 (file)
@@ -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<numeric>(arg))
+               return abs(ex_to<numeric>(arg));
        
-       return abs(ex_to<numeric>(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<numeric>(arg))
+               return csgn(ex_to<numeric>(arg));
        
-       return csgn(ex_to<numeric>(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<numeric>(x))
+               return Li2(ex_to<numeric>(x));
        
-       return Li2(ex_to<numeric>(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<numeric>(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());
        
index 4377efdefa73c0c2d17c87746e0a57c3220854a5..9c1da65157426b2cb960fd29f7f491c2012b57f6 100644 (file)
@@ -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<numeric>(x)) {
+               try {
+                       return lgamma(ex_to<numeric>(x));
+               } catch (const dunno &e) { }
+       }
        
-       return lgamma(ex_to<numeric>(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<numeric>(x)) {
+               try {
+                       return tgamma(ex_to<numeric>(x));
+               } catch (const dunno &e) { }
+       }
        
-       return tgamma(ex_to<numeric>(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<numeric>(x) && is_exactly_a<numeric>(y)) {
+               try {
+                       return tgamma(ex_to<numeric>(x))*tgamma(ex_to<numeric>(y))/tgamma(ex_to<numeric>(x+y));
+               } catch (const dunno &e) { }
+       }
        
-       return tgamma(ex_to<numeric>(x))*tgamma(ex_to<numeric>(y))/tgamma(ex_to<numeric>(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<numeric>(x)) {
+               try {
+                       return psi(ex_to<numeric>(x));
+               } catch (const dunno &e) { }
+       }
        
-       return psi(ex_to<numeric>(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<numeric>(n) && is_exactly_a<numeric>(x)) {
+               try {
+                       return psi(ex_to<numeric>(n),ex_to<numeric>(x));
+               } catch (const dunno &e) { }
+       }
        
-       return psi(ex_to<numeric>(n), ex_to<numeric>(x));
+       return psi(n,x).hold();
 }
 
 /** Evaluation of polygamma-function psi(n,x). 
index 150e3428f49fb4323f78dbd011bbee1d8907ff9a..a626ce1c29332370ad13e471554e3cf4f5260ba0 100644 (file)
@@ -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<numeric>(x))
+               return exp(ex_to<numeric>(x));
        
-       return exp(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return log(ex_to<numeric>(x));
        
-       return log(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return sin(ex_to<numeric>(x));
        
-       return sin(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return cos(ex_to<numeric>(x));
        
-       return cos(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return tan(ex_to<numeric>(x));
        
-       return tan(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return asin(ex_to<numeric>(x));
        
-       return asin(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return acos(ex_to<numeric>(x));
        
-       return acos(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return atan(ex_to<numeric>(x));
        
-       return atan(ex_to<numeric>(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<numeric>(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<numeric>(y) && is_exactly_a<numeric>(x))
+               return atan2(ex_to<numeric>(y), ex_to<numeric>(x));
        
-       return atan(ex_to<numeric>(y),ex_to<numeric>(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<numeric>(x))
+               return sinh(ex_to<numeric>(x));
        
-       return sinh(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return cosh(ex_to<numeric>(x));
        
-       return cosh(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return tanh(ex_to<numeric>(x));
        
-       return tanh(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return asinh(ex_to<numeric>(x));
        
-       return asinh(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return acosh(ex_to<numeric>(x));
        
-       return acosh(ex_to<numeric>(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<numeric>(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<numeric>(x))
+               return atanh(ex_to<numeric>(x));
        
-       return atanh(ex_to<numeric>(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<numeric>(x));
        }
        
        return atanh(x).hold();
index 9cd0961af432694e0aed9a1c40ab26a50ead2918..53eba05bb23107e1119b11568638da5ff954b15f 100644 (file)
@@ -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<numeric>(x));
+       if (is_exactly_a<numeric>(x)) {
+               try {
+                       return zeta(ex_to<numeric>(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();
 }
index f39de456a20a312b32148e9d4aea7df221488c56..e4757b9d8181584e48f6f91de150e5b889fb74dd 100644 (file)
@@ -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<lst>(l))
                return;
        for (unsigned i=0; i<l.nops(); i++) {
-               if (is_ex_exactly_of_type(l.op(i), symbol))
-                       syms[ex_to_symbol(l.op(i)).get_name()] = sym_def(l.op(i), true);
+               if (is_exactly_a<symbol>(l.op(i)))
+                       syms[ex_to<symbol>(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<symbol>(s).get_name());
        if (i == syms.end())
                return false;
        else
index ba9b8210ed250a706ca90786158e0905bf82e382..0303b6d7ccee81b647e6d4777819b8a061c8f662 100644 (file)
@@ -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();
 }
 
 
index 001f64f45071473d8dfb1ee258dcf691df4f4b29..78334b17d25ac4047b5a7d35eef4e83841b0edb1 100644 (file)
@@ -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<const TYPE *>(&OBJ)!=0)
+
+#define is_exactly_of_type(OBJ,TYPE) \
+       ((OBJ).tinfo()==GiNaC::TINFO_##TYPE)
+
+#define is_ex_of_type(OBJ,TYPE) \
+       (dynamic_cast<const TYPE *>((OBJ).bp)!=0)
+
+#define is_ex_exactly_of_type(OBJ,TYPE) \
+       ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE)
+
 } // namespace GiNaC
 
+
 #endif // ndef __GINAC_UTILS_H__