]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.cpp
* zeta(n,x) is now zetaderiv(n,s)
[ginac.git] / ginac / numeric.cpp
index c69a117d3748c0da1ed9fd26385143b5529a2361..f8e4d93b406222046357042188ad12acb42ef9df 100644 (file)
@@ -34,7 +34,6 @@
 
 #include "numeric.h"
 #include "ex.h"
-#include "print.h"
 #include "operators.h"
 #include "archive.h"
 #include "tostring.h"
 
 namespace GiNaC {
 
-GINAC_IMPLEMENT_REGISTERED_CLASS(numeric, basic)
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(numeric, basic,
+  print_func<print_context>(&numeric::do_print).
+  print_func<print_latex>(&numeric::do_print_latex).
+  print_func<print_csrc>(&numeric::do_print_csrc).
+  print_func<print_csrc_cl_N>(&numeric::do_print_csrc_cl_N).
+  print_func<print_tree>(&numeric::do_print_tree).
+  print_func<print_python_repr>(&numeric::do_print_python_repr))
 
 //////////
 // default constructor
@@ -410,140 +415,148 @@ static void print_real_cl_N(const print_context & c, const cln::cl_R & x)
        }
 }
 
-/** This method adds to the output so it blends more consistently together
- *  with the other routines and produces something compatible to ginsh input.
- *  
- *  @see print_real_number() */
-void numeric::print(const print_context & c, unsigned level) const
+void numeric::print_numeric(const print_context & c, const char *par_open, const char *par_close, const char *imag_sym, const char *mul_sym, unsigned level) const
 {
-       if (is_a<print_tree>(c)) {
+       const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
+       const cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
 
-               c.s << std::string(level, ' ') << cln::the<cln::cl_N>(value)
-                   << " (" << class_name() << ")"
-                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
-                   << std::endl;
+       if (cln::zerop(i)) {
 
-       } else if (is_a<print_csrc_cl_N>(c)) {
+               // case 1, real:  x  or  -x
+               if ((precedence() <= level) && (!this->is_nonneg_integer())) {
+                       c.s << par_open;
+                       print_real_number(c, r);
+                       c.s << par_close;
+               } else {
+                       print_real_number(c, r);
+               }
 
-               // CLN output
-               if (this->is_real()) {
+       } else {
+               if (cln::zerop(r)) {
 
-                       // Real number
-                       print_real_cl_N(c, cln::the<cln::cl_R>(value));
+                       // case 2, imaginary:  y*I  or  -y*I
+                       if (i == 1)
+                               c.s << imag_sym;
+                       else {
+                               if (precedence()<=level)
+                                       c.s << par_open;
+                               if (i == -1)
+                                       c.s << "-" << imag_sym;
+                               else {
+                                       print_real_number(c, i);
+                                       c.s << mul_sym << imag_sym;
+                               }
+                               if (precedence()<=level)
+                                       c.s << par_close;
+                       }
 
                } else {
 
-                       // Complex number
-                       c.s << "cln::complex(";
-                       print_real_cl_N(c, cln::realpart(cln::the<cln::cl_N>(value)));
-                       c.s << ",";
-                       print_real_cl_N(c, cln::imagpart(cln::the<cln::cl_N>(value)));
-                       c.s << ")";
+                       // case 3, complex:  x+y*I  or  x-y*I  or  -x+y*I  or  -x-y*I
+                       if (precedence() <= level)
+                               c.s << par_open;
+                       print_real_number(c, r);
+                       if (i < 0) {
+                               if (i == -1) {
+                                       c.s << "-" << imag_sym;
+                               } else {
+                                       print_real_number(c, i);
+                                       c.s << mul_sym << imag_sym;
+                               }
+                       } else {
+                               if (i == 1) {
+                                       c.s << "+" << imag_sym;
+                               } else {
+                                       c.s << "+";
+                                       print_real_number(c, i);
+                                       c.s << mul_sym << imag_sym;
+                               }
+                       }
+                       if (precedence() <= level)
+                               c.s << par_close;
                }
+       }
+}
 
-       } else if (is_a<print_csrc>(c)) {
+void numeric::do_print(const print_context & c, unsigned level) const
+{
+       print_numeric(c, "(", ")", "I", "*", level);
+}
 
-               // C++ source output
-               std::ios::fmtflags oldflags = c.s.flags();
-               c.s.setf(std::ios::scientific);
-               int oldprec = c.s.precision();
+void numeric::do_print_latex(const print_latex & c, unsigned level) const
+{
+       print_numeric(c, "{(", ")}", "i", " ", level);
+}
 
-               // Set precision
-               if (is_a<print_csrc_double>(c))
-                       c.s.precision(std::numeric_limits<double>::digits10 + 1);
-               else
-                       c.s.precision(std::numeric_limits<float>::digits10 + 1);
+void numeric::do_print_csrc(const print_csrc & c, unsigned level) const
+{
+       std::ios::fmtflags oldflags = c.s.flags();
+       c.s.setf(std::ios::scientific);
+       int oldprec = c.s.precision();
 
-               if (this->is_real()) {
+       // Set precision
+       if (is_a<print_csrc_double>(c))
+               c.s.precision(std::numeric_limits<double>::digits10 + 1);
+       else
+               c.s.precision(std::numeric_limits<float>::digits10 + 1);
 
-                       // Real number
-                       print_real_csrc(c, cln::the<cln::cl_R>(value));
+       if (this->is_real()) {
 
-               } else {
+               // Real number
+               print_real_csrc(c, cln::the<cln::cl_R>(value));
 
-                       // Complex number
-                       c.s << "std::complex<";
-                       if (is_a<print_csrc_double>(c))
-                               c.s << "double>(";
-                       else
-                               c.s << "float>(";
+       } else {
 
-                       print_real_csrc(c, cln::realpart(cln::the<cln::cl_N>(value)));
-                       c.s << ",";
-                       print_real_csrc(c, cln::imagpart(cln::the<cln::cl_N>(value)));
-                       c.s << ")";
-               }
+               // Complex number
+               c.s << "std::complex<";
+               if (is_a<print_csrc_double>(c))
+                       c.s << "double>(";
+               else
+                       c.s << "float>(";
+
+               print_real_csrc(c, cln::realpart(cln::the<cln::cl_N>(value)));
+               c.s << ",";
+               print_real_csrc(c, cln::imagpart(cln::the<cln::cl_N>(value)));
+               c.s << ")";
+       }
+
+       c.s.flags(oldflags);
+       c.s.precision(oldprec);
+}
 
-               c.s.flags(oldflags);
-               c.s.precision(oldprec);
+void numeric::do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const
+{
+       if (this->is_real()) {
+
+               // Real number
+               print_real_cl_N(c, cln::the<cln::cl_R>(value));
 
        } else {
 
-               const std::string par_open  = is_a<print_latex>(c) ? "{(" : "(";
-               const std::string par_close = is_a<print_latex>(c) ? ")}" : ")";
-               const std::string imag_sym  = is_a<print_latex>(c) ? "i" : "I";
-               const std::string mul_sym   = is_a<print_latex>(c) ? " " : "*";
-               const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
-               const cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
-
-               if (is_a<print_python_repr>(c))
-                       c.s << class_name() << "('";
-               if (cln::zerop(i)) {
-                       // case 1, real:  x  or  -x
-                       if ((precedence() <= level) && (!this->is_nonneg_integer())) {
-                               c.s << par_open;
-                               print_real_number(c, r);
-                               c.s << par_close;
-                       } else {
-                               print_real_number(c, r);
-                       }
-               } else {
-                       if (cln::zerop(r)) {
-                               // case 2, imaginary:  y*I  or  -y*I
-                               if (i==1)
-                                       c.s << imag_sym;
-                               else {
-                                       if (precedence()<=level)
-                                               c.s << par_open;
-                                       if (i == -1)
-                                               c.s << "-" << imag_sym;
-                                       else {
-                                               print_real_number(c, i);
-                                               c.s << mul_sym+imag_sym;
-                                       }
-                                       if (precedence()<=level)
-                                               c.s << par_close;
-                               }
-                       } else {
-                               // case 3, complex:  x+y*I  or  x-y*I  or  -x+y*I  or  -x-y*I
-                               if (precedence() <= level)
-                                       c.s << par_open;
-                               print_real_number(c, r);
-                               if (i < 0) {
-                                       if (i == -1) {
-                                               c.s << "-"+imag_sym;
-                                       } else {
-                                               print_real_number(c, i);
-                                               c.s << mul_sym+imag_sym;
-                                       }
-                               } else {
-                                       if (i == 1) {
-                                               c.s << "+"+imag_sym;
-                                       } else {
-                                               c.s << "+";
-                                               print_real_number(c, i);
-                                               c.s << mul_sym+imag_sym;
-                                       }
-                               }
-                               if (precedence() <= level)
-                                       c.s << par_close;
-                       }
-               }
-               if (is_a<print_python_repr>(c))
-                       c.s << "')";
+               // Complex number
+               c.s << "cln::complex(";
+               print_real_cl_N(c, cln::realpart(cln::the<cln::cl_N>(value)));
+               c.s << ",";
+               print_real_cl_N(c, cln::imagpart(cln::the<cln::cl_N>(value)));
+               c.s << ")";
        }
 }
 
+void numeric::do_print_tree(const print_tree & c, unsigned level) const
+{
+       c.s << std::string(level, ' ') << cln::the<cln::cl_N>(value)
+           << " (" << class_name() << ")" << " @" << this
+           << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+           << std::endl;
+}
+
+void numeric::do_print_python_repr(const print_python_repr & c, unsigned level) const
+{
+       c.s << class_name() << "('";
+       print_numeric(c, "(", ")", "I", "*", level);
+       c.s << "')";
+}
+
 bool numeric::info(unsigned inf) const
 {
        switch (inf) {
@@ -1274,14 +1287,14 @@ const numeric exp(const numeric &x)
 
 /** Natural logarithm.
  *
- *  @param z complex number
+ *  @param x complex number
  *  @return  arbitrary precision numerical log(x).
  *  @exception pole_error("log(): logarithmic pole",0) */
-const numeric log(const numeric &z)
+const numeric log(const numeric &x)
 {
-       if (z.is_zero())
+       if (x.is_zero())
                throw pole_error("log(): logarithmic pole",0);
-       return cln::log(z.to_cl_N());
+       return cln::log(x.to_cl_N());
 }
 
 
@@ -1332,8 +1345,8 @@ const numeric acos(const numeric &x)
 
 /** Arcustangent.
  *
- *  @param z complex number
- *  @return atan(z)
+ *  @param x complex number
+ *  @return atan(x)
  *  @exception pole_error("atan(): logarithmic pole",0) */
 const numeric atan(const numeric &x)
 {
@@ -1914,16 +1927,16 @@ const numeric lcm(const numeric &a, const numeric &b)
 
 
 /** Numeric square root.
- *  If possible, sqrt(z) should respect squares of exact numbers, i.e. sqrt(4)
+ *  If possible, sqrt(x) should respect squares of exact numbers, i.e. sqrt(4)
  *  should return integer 2.
  *
- *  @param z numeric argument
- *  @return square root of z. Branch cut along negative real axis, the negative
- *  real axis itself where imag(z)==0 and real(z)<0 belongs to the upper part
- *  where imag(z)>0. */
-const numeric sqrt(const numeric &z)
+ *  @param x numeric argument
+ *  @return square root of x. Branch cut along negative real axis, the negative
+ *  real axis itself where imag(x)==0 and real(x)<0 belongs to the upper part
+ *  where imag(x)>0. */
+const numeric sqrt(const numeric &x)
 {
-       return cln::sqrt(z.to_cl_N());
+       return cln::sqrt(x.to_cl_N());
 }