X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Finifcns_trans.cpp;h=c12df144c8bcedeb534318f57bba695b2a053520;hp=9db0cbd11c9c527c74c1646343c2945ee79e2d5e;hb=f16bf92e181b45c3caca15c6428bab0733accf1c;hpb=e7cc6a764ff67b5885d6633385fac23ccc1dc9a7;ds=sidebyside diff --git a/ginac/inifcns_trans.cpp b/ginac/inifcns_trans.cpp index 9db0cbd1..c12df144 100644 --- a/ginac/inifcns_trans.cpp +++ b/ginac/inifcns_trans.cpp @@ -4,7 +4,7 @@ * functions. */ /* - * GiNaC Copyright (C) 1999-2002 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2004 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ #include "constant.h" #include "numeric.h" #include "power.h" +#include "operators.h" #include "relational.h" #include "symbol.h" #include "pseries.h" @@ -123,6 +124,9 @@ static ex log_eval(const ex & x) // log(exp(t)) -> t (if -Pi < t.imag() <= Pi): if (is_ex_the_function(x, exp)) { const ex &t = x.op(0); + if (is_a(t) && t.info(info_flags::real)) { + return t; + } if (t.info(info_flags::numeric)) { const numeric &nt = ex_to(t); if (nt.is_real()) @@ -141,25 +145,17 @@ static ex log_deriv(const ex & x, unsigned deriv_param) return power(x, _ex_1); } -// This is a strange workaround for a compiliation problem with the try statement -// below. With -O1 the exception is not caucht properly as of GCC-2.95.2, at -// least on i386. Version 2.95.4 seems to have fixed this silly problem, though. -// Funnily, with a simple extern declaration here it mysteriously works again. -#if defined(__GNUC__) && (__GNUC__==2) -extern "C" int putchar(int); -#endif - static ex log_series(const ex &arg, const relational &rel, int order, unsigned options) { - GINAC_ASSERT(is_exactly_a(rel.lhs())); + GINAC_ASSERT(is_a(rel.lhs())); ex arg_pt; bool must_expand_arg = false; // maybe substitution of rel into arg fails because of a pole try { - arg_pt = arg.subs(rel); + arg_pt = arg.subs(rel, subs_options::no_pattern); } catch (pole_error) { must_expand_arg = true; } @@ -213,7 +209,7 @@ static ex log_series(const ex &arg, const symbol &s = ex_to(rel.lhs()); const ex &point = rel.rhs(); const symbol foo; - const ex replarg = series(log(arg), s==foo, order).subs(foo==point); + const ex replarg = series(log(arg), s==foo, order).subs(foo==point, subs_options::no_pattern); epvector seq; seq.push_back(expair(-I*csgn(arg*I)*Pi, _ex0)); seq.push_back(expair(Order(_ex1), order)); @@ -468,15 +464,15 @@ static ex tan_series(const ex &x, int order, unsigned options) { - GINAC_ASSERT(is_exactly_a(rel.lhs())); + GINAC_ASSERT(is_a(rel.lhs())); // method: // Taylor series where there is no pole falls back to tan_deriv. // On a pole simply expand sin(x)/cos(x). - const ex x_pt = x.subs(rel); + const ex x_pt = x.subs(rel, subs_options::no_pattern); if (!(2*x_pt/Pi).info(info_flags::odd)) throw do_taylor(); // caught by function::series() // if we got here we have to care for a simple pole - return (sin(x)/cos(x)).series(rel, order+2, options); + return (sin(x)/cos(x)).series(rel, order, options); } REGISTER_FUNCTION(tan, eval_func(tan_eval). @@ -634,7 +630,7 @@ static ex atan_series(const ex &arg, int order, unsigned options) { - GINAC_ASSERT(is_exactly_a(rel.lhs())); + GINAC_ASSERT(is_a(rel.lhs())); // method: // Taylor series where there is no pole or cut falls back to atan_deriv. // There are two branch cuts, one runnig from I up the imaginary axis and @@ -643,7 +639,7 @@ static ex atan_series(const ex &arg, // On the branch cuts and the poles series expand // (log(1+I*x)-log(1-I*x))/(2*I) // instead. - const ex arg_pt = arg.subs(rel); + const ex arg_pt = arg.subs(rel, subs_options::no_pattern); if (!(I*arg_pt).info(info_flags::real)) throw do_taylor(); // Re(x) != 0 if ((I*arg_pt).info(info_flags::real) && abs(I*arg_pt)<_ex1) @@ -658,7 +654,7 @@ static ex atan_series(const ex &arg, const symbol &s = ex_to(rel.lhs()); const ex &point = rel.rhs(); const symbol foo; - const ex replarg = series(atan(arg), s==foo, order).subs(foo==point); + const ex replarg = series(atan(arg), s==foo, order).subs(foo==point, subs_options::no_pattern); ex Order0correction = replarg.op(0)+csgn(arg)*Pi*_ex_1_2; if ((I*arg_pt)<_ex0) Order0correction += log((I*arg_pt+_ex_1)/(I*arg_pt+_ex1))*I*_ex_1_2; @@ -878,15 +874,15 @@ static ex tanh_series(const ex &x, int order, unsigned options) { - GINAC_ASSERT(is_exactly_a(rel.lhs())); + GINAC_ASSERT(is_a(rel.lhs())); // method: // Taylor series where there is no pole falls back to tanh_deriv. // On a pole simply expand sinh(x)/cosh(x). - const ex x_pt = x.subs(rel); + const ex x_pt = x.subs(rel, subs_options::no_pattern); if (!(2*I*x_pt/Pi).info(info_flags::odd)) throw do_taylor(); // caught by function::series() // if we got here we have to care for a simple pole - return (sinh(x)/cosh(x)).series(rel, order+2, options); + return (sinh(x)/cosh(x)).series(rel, order, options); } REGISTER_FUNCTION(tanh, eval_func(tanh_eval). @@ -1019,7 +1015,7 @@ static ex atanh_series(const ex &arg, int order, unsigned options) { - GINAC_ASSERT(is_exactly_a(rel.lhs())); + GINAC_ASSERT(is_a(rel.lhs())); // method: // Taylor series where there is no pole or cut falls back to atanh_deriv. // There are two branch cuts, one runnig from 1 up the real axis and one @@ -1027,7 +1023,7 @@ static ex atanh_series(const ex &arg, // On the branch cuts and the poles series expand // (log(1+x)-log(1-x))/2 // instead. - const ex arg_pt = arg.subs(rel); + const ex arg_pt = arg.subs(rel, subs_options::no_pattern); if (!(arg_pt).info(info_flags::real)) throw do_taylor(); // Im(x) != 0 if ((arg_pt).info(info_flags::real) && abs(arg_pt)<_ex1) @@ -1043,7 +1039,7 @@ static ex atanh_series(const ex &arg, const symbol &s = ex_to(rel.lhs()); const ex &point = rel.rhs(); const symbol foo; - const ex replarg = series(atanh(arg), s==foo, order).subs(foo==point); + const ex replarg = series(atanh(arg), s==foo, order).subs(foo==point, subs_options::no_pattern); ex Order0correction = replarg.op(0)+csgn(I*arg)*Pi*I*_ex1_2; if (arg_pt<_ex0) Order0correction += log((arg_pt+_ex_1)/(arg_pt+_ex1))*_ex1_2;