X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Finifcns.cpp;h=f7d2864ef9ae64035eae269d140b6c36b6d41169;hp=fcf2d05dc088052d60e7d12f9e577b7a103cd4f9;hb=af0c47009ca7a15af966430bdf1a72fe05c1c6f9;hpb=8d08b902f1bb734fe91b5aa29c66c59788464be7 diff --git a/ginac/inifcns.cpp b/ginac/inifcns.cpp index fcf2d05d..f7d2864e 100644 --- a/ginac/inifcns.cpp +++ b/ginac/inifcns.cpp @@ -65,6 +65,67 @@ static ex abs_eval(const ex & x) REGISTER_FUNCTION(abs, eval_func(abs_eval). evalf_func(abs_evalf)); + +////////// +// Complex sign +////////// + +static ex csgn_evalf(const ex & x) +{ + BEGIN_TYPECHECK + TYPECHECK(x,numeric) + END_TYPECHECK(csgn(x)) + + return csgn(ex_to_numeric(x)); +} + +static ex csgn_eval(const ex & x) +{ + if (is_ex_exactly_of_type(x, numeric)) + return csgn(ex_to_numeric(x)); + + if (is_ex_exactly_of_type(x, mul)) { + numeric oc = ex_to_numeric(x.op(x.nops()-1)); + if (oc.is_real()) { + if (oc > 0) + // csgn(42*x) -> csgn(x) + return csgn(x/oc).hold(); + else + // csgn(-42*x) -> -csgn(x) + return -csgn(x/oc).hold(); + } + if (oc.real().is_zero()) { + if (oc.imag() > 0) + // csgn(42*I*x) -> csgn(I*x) + return csgn(I*x/oc).hold(); + else + // csgn(-42*I*x) -> -csgn(I*x) + return -csgn(I*x/oc).hold(); + } + } + + return csgn(x).hold(); +} + +static ex csgn_series(const ex & x, const relational & rel, int order) +{ + const ex x_pt = x.subs(rel); + if (x_pt.info(info_flags::numeric)) { + if (ex_to_numeric(x_pt).real().is_zero()) + throw (std::domain_error("csgn_series(): on imaginary axis")); + epvector seq; + seq.push_back(expair(csgn(x_pt), _ex0())); + return pseries(rel,seq); + } + epvector seq; + seq.push_back(expair(csgn(x_pt), _ex0())); + return pseries(rel,seq); +} + +REGISTER_FUNCTION(csgn, eval_func(csgn_eval). + evalf_func(csgn_evalf). + series_func(csgn_series)); + ////////// // dilogarithm ////////// @@ -158,12 +219,14 @@ static ex Order_eval(const ex & x) return Order(x).hold(); } -static ex Order_series(const ex & x, const symbol & s, const ex & point, int order) +static ex Order_series(const ex & x, const relational & r, int order) { // Just wrap the function into a pseries object epvector new_seq; - new_seq.push_back(expair(Order(_ex1()), numeric(min(x.ldegree(s), order)))); - return pseries(s, point, new_seq); + GINAC_ASSERT(is_ex_exactly_of_type(r.lhs(),symbol)); + const symbol *s = static_cast(r.lhs().bp); + new_seq.push_back(expair(Order(_ex1()), numeric(min(x.ldegree(*s), order)))); + return pseries(r, new_seq); } // Differentiation is handled in function::derivative because of its special requirements @@ -299,7 +362,7 @@ ex ncpower(const ex &basis, unsigned exponent) /** Force inclusion of functions from initcns_gamma and inifcns_zeta * for static lib (so ginsh will see them). */ -unsigned force_include_gamma = function_index_Gamma; +unsigned force_include_tgamma = function_index_tgamma; unsigned force_include_zeta1 = function_index_zeta1; #ifndef NO_NAMESPACE_GINAC