* Implementation of GiNaC's initially known functions. */
/*
- * GiNaC Copyright (C) 1999-2003 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
namespace GiNaC {
+//////////
+// complex conjugate
+//////////
+
+static ex conjugate_evalf(const ex & arg)
+{
+ if (is_exactly_a<numeric>(arg)) {
+ return ex_to<numeric>(arg).conjugate();
+ }
+ return conjugate_function(arg).hold();
+}
+
+static ex conjugate_eval(const ex & arg)
+{
+ return arg.conjugate();
+}
+
+static void conjugate_print_latex(const ex & arg, const print_context & c)
+{
+ c.s << "\\bar{"; arg.print(c); c.s << "}";
+}
+
+static ex conjugate_conjugate(const ex & arg)
+{
+ return arg;
+}
+
+REGISTER_FUNCTION(conjugate_function, eval_func(conjugate_eval).
+ evalf_func(conjugate_evalf).
+ print_func<print_latex>(conjugate_print_latex).
+ conjugate_func(conjugate_conjugate).
+ set_name("conjugate","conjugate"));
+
//////////
// absolute value
//////////
c.s << "fabs("; arg.print(c); c.s << ")";
}
+static ex abs_conjugate(const ex & arg)
+{
+ return abs(arg);
+}
+
REGISTER_FUNCTION(abs, eval_func(abs_eval).
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));
+ print_func<print_csrc_double>(abs_print_csrc_float).
+ conjugate_func(abs_conjugate));
//////////
return pseries(rel,seq);
}
+static ex csgn_conjugate(const ex& arg)
+{
+ return csgn(arg);
+}
+
REGISTER_FUNCTION(csgn, eval_func(csgn_eval).
evalf_func(csgn_evalf).
- series_func(csgn_series));
+ series_func(csgn_series).
+ conjugate_func(csgn_conjugate));
//////////
return pseries(rel,seq);
}
+static ex eta_conjugate(const ex & x, const ex & y)
+{
+ return -eta(x,y);
+}
+
REGISTER_FUNCTION(eta, eval_func(eta_eval).
evalf_func(eta_evalf).
series_func(eta_series).
latex_name("\\eta").
- set_symmetry(sy_symm(0, 1)));
+ set_symmetry(sy_symm(0, 1)).
+ conjugate_func(eta_conjugate));
//////////
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
//////////
return factorial(x).hold();
}
+static ex factorial_conjugate(const ex & x)
+{
+ return factorial(x);
+}
+
REGISTER_FUNCTION(factorial, eval_func(factorial_eval).
- evalf_func(factorial_evalf));
+ evalf_func(factorial_evalf).
+ conjugate_func(factorial_conjugate));
//////////
// binomial
return binomial(x, y).hold();
}
+static ex binomial_sym(const ex & x, const numeric & y)
+{
+ if (y.is_integer()) {
+ if (y.is_nonneg_integer()) {
+ const unsigned N = y.to_int();
+ if (N == 0) return _num0;
+ if (N == 1) return x;
+ ex t = x.expand();
+ for (unsigned i = 2; i <= N; ++i)
+ t = (t * (x + i - y - 1)).expand() / i;
+ return t;
+ } else
+ return _num0;
+ }
+
+ return binomial(x, y).hold();
+}
+
static ex binomial_eval(const ex & x, const ex &y)
{
- if (is_exactly_a<numeric>(x) && is_exactly_a<numeric>(y))
- return binomial(ex_to<numeric>(x), ex_to<numeric>(y));
- else
+ if (is_exactly_a<numeric>(y)) {
+ if (is_exactly_a<numeric>(x) && ex_to<numeric>(x).is_integer())
+ return binomial(ex_to<numeric>(x), ex_to<numeric>(y));
+ else
+ return binomial_sym(x, ex_to<numeric>(y));
+ } else
return binomial(x, y).hold();
}
+// At the moment the numeric evaluation of a binomail function always
+// gives a real number, but if this would be implemented using the gamma
+// function, also complex conjugation should be changed (or rather, deleted).
+static ex binomial_conjugate(const ex & x, const ex & y)
+{
+ return binomial(x,y);
+}
+
REGISTER_FUNCTION(binomial, eval_func(binomial_eval).
- evalf_func(binomial_evalf));
+ evalf_func(binomial_evalf).
+ conjugate_func(binomial_conjugate));
//////////
// Order term function (for truncated power series)
return pseries(r, new_seq);
}
+static ex Order_conjugate(const ex & x)
+{
+ return Order(x);
+}
+
// Differentiation is handled in function::derivative because of its special requirements
REGISTER_FUNCTION(Order, eval_func(Order_eval).
series_func(Order_series).
- latex_name("\\mathcal{O}"));
+ latex_name("\\mathcal{O}").
+ conjugate_func(Order_conjugate));
//////////
// Solve linear system