+//////////
+// real part
+//////////
+
+static ex real_part_evalf(const ex & arg)
+{
+ if (is_exactly_a<numeric>(arg)) {
+ return ex_to<numeric>(arg).real();
+ }
+ return real_part_function(arg).hold();
+}
+
+static ex real_part_eval(const ex & arg)
+{
+ return arg.real_part();
+}
+
+static void real_part_print_latex(const ex & arg, const print_context & c)
+{
+ c.s << "\\Re"; arg.print(c); c.s << "";
+}
+
+static ex real_part_conjugate(const ex & arg)
+{
+ return real_part_function(arg).hold();
+}
+
+static ex real_part_real_part(const ex & arg)
+{
+ return real_part_function(arg).hold();
+}
+
+static ex real_part_imag_part(const ex & arg)
+{
+ return 0;
+}
+
+// If x is real then Re(e).diff(x) is equal to Re(e.diff(x))
+static ex real_part_expl_derivative(const ex & arg, const symbol & s)
+{
+ if (s.info(info_flags::real))
+ return real_part_function(arg.diff(s));
+ else {
+ exvector vec_arg;
+ vec_arg.push_back(arg);
+ return fderivative(ex_to<function>(real_part(arg)).get_serial(),0,vec_arg).hold()*arg.diff(s);
+ }
+}
+
+REGISTER_FUNCTION(real_part_function, eval_func(real_part_eval).
+ evalf_func(real_part_evalf).
+ expl_derivative_func(real_part_expl_derivative).
+ print_func<print_latex>(real_part_print_latex).
+ conjugate_func(real_part_conjugate).
+ real_part_func(real_part_real_part).
+ imag_part_func(real_part_imag_part).
+ set_name("real_part","real_part"));
+
+//////////
+// imag part
+//////////
+
+static ex imag_part_evalf(const ex & arg)
+{
+ if (is_exactly_a<numeric>(arg)) {
+ return ex_to<numeric>(arg).imag();
+ }
+ return imag_part_function(arg).hold();
+}
+
+static ex imag_part_eval(const ex & arg)
+{
+ return arg.imag_part();
+}
+
+static void imag_part_print_latex(const ex & arg, const print_context & c)
+{
+ c.s << "\\Im"; arg.print(c); c.s << "";
+}
+
+static ex imag_part_conjugate(const ex & arg)
+{
+ return imag_part_function(arg).hold();
+}
+
+static ex imag_part_real_part(const ex & arg)
+{
+ return imag_part_function(arg).hold();
+}
+
+static ex imag_part_imag_part(const ex & arg)
+{
+ return 0;
+}
+
+// If x is real then Im(e).diff(x) is equal to Im(e.diff(x))
+static ex imag_part_expl_derivative(const ex & arg, const symbol & s)
+{
+ if (s.info(info_flags::real))
+ return imag_part_function(arg.diff(s));
+ else {
+ exvector vec_arg;
+ vec_arg.push_back(arg);
+ return fderivative(ex_to<function>(imag_part(arg)).get_serial(),0,vec_arg).hold()*arg.diff(s);
+ }
+}
+
+REGISTER_FUNCTION(imag_part_function, eval_func(imag_part_eval).
+ evalf_func(imag_part_evalf).
+ expl_derivative_func(imag_part_expl_derivative).
+ print_func<print_latex>(imag_part_print_latex).
+ conjugate_func(imag_part_conjugate).
+ real_part_func(imag_part_real_part).
+ imag_part_func(imag_part_imag_part).
+ set_name("imag_part","imag_part"));
+