return abs(arg).hold();
}
+static void abs_print_latex(const ex & arg, const print_context & c)
+{
+ c.s << "{|"; arg.print(c); c.s << "|}";
+}
+
+static void abs_print_csrc_float(const ex & arg, const print_context & c)
+{
+ c.s << "fabs("; arg.print(c); c.s << ")";
+}
+
REGISTER_FUNCTION(abs, eval_func(abs_eval).
- evalf_func(abs_evalf));
+ evalf_func(abs_evalf).
+ print_func<print_latex>(abs_print_latex).
+ print_func<print_csrc_float>(abs_print_csrc_float).
+ print_func<print_csrc_double>(abs_print_csrc_float));
//////////
int order,
unsigned options)
{
- const ex arg_pt = arg.subs(rel);
+ const ex arg_pt = arg.subs(rel, subs_options::no_pattern);
if (arg_pt.info(info_flags::numeric)
&& ex_to<numeric>(arg_pt).real().is_zero()
&& !(options & series_options::suppress_branchcut))
int order,
unsigned options)
{
- const ex x_pt = x.subs(rel);
- const ex y_pt = y.subs(rel);
+ const ex x_pt = x.subs(rel, subs_options::no_pattern);
+ const ex y_pt = y.subs(rel, subs_options::no_pattern);
if ((x_pt.info(info_flags::numeric) && x_pt.info(info_flags::negative)) ||
(y_pt.info(info_flags::numeric) && y_pt.info(info_flags::negative)) ||
((x_pt*y_pt).info(info_flags::numeric) && (x_pt*y_pt).info(info_flags::negative)))
static ex Li2_series(const ex &x, const relational &rel, int order, unsigned options)
{
- const ex x_pt = x.subs(rel);
+ const ex x_pt = x.subs(rel, subs_options::no_pattern);
if (x_pt.info(info_flags::numeric)) {
// First special case: x==0 (derivatives have poles)
if (x_pt.is_zero()) {
for (int i=1; i<order; ++i)
ser += pow(s,i) / pow(numeric(i), _num2);
// substitute the argument's series expansion
- ser = ser.subs(s==x.series(rel, order));
+ ser = ser.subs(s==x.series(rel, order), subs_options::no_pattern);
// maybe that was terminating, so add a proper order term
epvector nseq;
nseq.push_back(expair(Order(_ex1), order));
for (int i=1; i<order; ++i)
ser += pow(1-s,i) * (numeric(1,i)*(I*Pi+log(s-1)) - numeric(1,i*i));
// substitute the argument's series expansion
- ser = ser.subs(s==x.series(rel, order));
+ ser = ser.subs(s==x.series(rel, order), subs_options::no_pattern);
// maybe that was terminating, so add a proper order term
epvector nseq;
nseq.push_back(expair(Order(_ex1), order));
// compute the intermediate terms:
ex replarg = series(Li2(x), s==foo, order);
for (size_t i=1; i<replarg.nops()-1; ++i)
- seq.push_back(expair((replarg.op(i)/power(s-foo,i)).series(foo==point,1,options).op(0).subs(foo==s),i));
+ seq.push_back(expair((replarg.op(i)/power(s-foo,i)).series(foo==point,1,options).op(0).subs(foo==s, subs_options::no_pattern),i));
// append an order term:
seq.push_back(expair(Order(_ex1), replarg.nops()-1));
return pseries(rel, seq);
REGISTER_FUNCTION(Li3, eval_func(Li3_eval).
latex_name("\\mbox{Li}_3"));
+//////////
+// Derivatives of Riemann's Zeta-function zetaderiv(0,x)==zeta(x)
+//////////
+
+static ex zetaderiv_eval(const ex & n, const ex & x)
+{
+ if (n.info(info_flags::numeric)) {
+ // zetaderiv(0,x) -> zeta(x)
+ if (n.is_zero())
+ return zeta(x);
+ }
+
+ return zetaderiv(n, x).hold();
+}
+
+static ex zetaderiv_deriv(const ex & n, const ex & x, unsigned deriv_param)
+{
+ GINAC_ASSERT(deriv_param<2);
+
+ if (deriv_param==0) {
+ // d/dn zeta(n,x)
+ throw(std::logic_error("cannot diff zetaderiv(n,x) with respect to n"));
+ }
+ // d/dx psi(n,x)
+ return zetaderiv(n+1,x);
+}
+
+REGISTER_FUNCTION(zetaderiv, eval_func(zetaderiv_eval).
+ derivative_func(zetaderiv_deriv).
+ latex_name("\\zeta^\\prime"));
+
//////////
// factorial
//////////