* basic::collec() never worked correctly on non-polynomials till now.
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sun, 15 Apr 2001 00:28:18 +0000 (00:28 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sun, 15 Apr 2001 00:28:18 +0000 (00:28 +0000)
  We simply correct for the missing terms, which makes it at least
  algebraically correct (suggested by Pearu Peterson).
* Added support to print out LaTeX-style, based on some work by Stefan
  Weinzierl:
  - print.h: added a class print_latex().
  - function.pl: added function_options::latex_name() because there was
    no good way of setting that name before.
  - inifncs*.cpp: use it.
  - *.cpp: switch to see if print_context is actually print_latex and
    then change the style.
* Fixed some stupid bugs in sections that were #define'd away for gcc-2.95.

17 files changed:
ginac/add.cpp
ginac/archive.cpp
ginac/archive.h
ginac/basic.cpp
ginac/constant.cpp
ginac/flags.h
ginac/function.pl
ginac/inifcns.cpp
ginac/inifcns_gamma.cpp
ginac/inifcns_trans.cpp
ginac/inifcns_zeta.cpp
ginac/mul.cpp
ginac/numeric.cpp
ginac/power.cpp
ginac/print.h
ginac/pseries.cpp
ginac/symbol.cpp

index 802c237..1b7b271 100644 (file)
@@ -166,8 +166,12 @@ void add::print(const print_context & c, unsigned level) const
 
        } else {
 
-               if (precedence <= level)
-                       c.s << "(";
+               if (precedence <= level) {
+                       if (is_of_type(c, print_latex))
+                               c.s << "{(";
+                       else
+                               c.s << "(";
+               }
 
                numeric coeff;
                bool first = true;
@@ -204,14 +208,21 @@ void add::print(const print_context & c, unsigned level) const
                                        else
                                                coeff.print(c, precedence);
                                }
-                               c.s << '*';
+                               if (is_of_type(c, print_latex))
+                                       c.s << ' ';
+                               else
+                                       c.s << '*';
                        }
                        it->rest.print(c, precedence);
                        it++;
                }
 
-               if (precedence <= level)
-                       c.s << ")";
+               if (precedence <= level) {
+                       if (is_of_type(c, print_latex))
+                               c.s << ")}";
+                       else
+                               c.s << ")";
+               }
        }
 }
 
index 3ce4ec6..cdd7619 100644 (file)
@@ -463,7 +463,7 @@ void archive_node::get_properties(propinfovector &v) const
        std::vector<property>::const_iterator i = props.begin(), iend = props.end();
        while (i != iend) {
                property_type type = i->type;
-               string name = a.unatomize(i->name);
+               std::string name = a.unatomize(i->name);
 
                propinfovector::iterator a = v.begin(), aend = v.end();
                bool found = false;
index 96a6ea1..5320439 100644 (file)
@@ -79,7 +79,7 @@ public:
 #if defined(__GNUC__) && ((__GNUC__ == 2) && (__GNUC_MINOR__ < 97))
        typedef std::vector<property_info,malloc_alloc> propinfovector;
 #else
-       typedef std::vector<ex> propinfovector;
+       typedef std::vector<property_info> propinfovector;
 #endif
 
        archive_node() : a(*dummy_ar_creator()), has_expression(false) {} // hack for cint which always requires a default constructor
index 8040e4a..c649f64 100644 (file)
@@ -243,10 +243,11 @@ ex basic::coeff(const ex & s, int n) const
 ex basic::collect(const ex & s) const
 {
        ex x;
-       for (int n=this->ldegree(s); n<=this->degree(s); n++)
+       for (int n=this->ldegree(s); n<=this->degree(s); ++n)
                x += this->coeff(s,n)*power(s,n);
        
-       return x;
+       // correct for lost fractional arguments and return
+       return x + (*this - x).expand();
 }
 
 /** Perform automatic non-interruptive symbolic evaluation on expression. */
index 7afc35b..c056a96 100644 (file)
@@ -132,11 +132,18 @@ void constant::print(const print_context & c, unsigned level) const
        debugmsg("constant print", LOGLEVEL_PRINT);
 
        if (is_of_type(c, print_tree)) {
-
                c.s << std::string(level, ' ') << name << " (" << class_name() << ")"
                    << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
                    << std::endl;
-
+       } else if (is_of_type(c, print_latex)) {
+               if (name=="Pi")
+                       c.s << "\\pi";
+               else if (name=="Euler")
+                       c.s << "\\gamma_E";
+               else if (name=="Catalan")
+                       c.s << "G";
+               else
+                       c.s << "\\mbox{"+name+"}";
        } else
                c.s << name;
 }
index 96838ce..9c11862 100644 (file)
@@ -69,7 +69,7 @@ public:
 class status_flags {
 public:
        enum {
-               dynallocated    = 0x0001,       ///< Heap-allocated (i.e. created by new if we want to be clever and bypass the stack)
+               dynallocated    = 0x0001,       ///< Heap-allocated (i.e. created by new if we want to be clever and bypass the stack, @see ex::construct_from_basic() )
                evaluated       = 0x0002,       ///< .eval() has already done its job
                expanded        = 0x0004,       ///< .expand() has already done its job
                hash_calculated = 0x0008        ///< .calchash() has already done its job
index d381ea6..9e303d0 100755 (executable)
@@ -264,6 +264,7 @@ public:
        ~function_options();
        void initialize(void);
        function_options & set_name(std::string const & n, std::string const & tn=std::string());
+       function_options & latex_name(std::string const & tn);
 // the following lines have been generated for max. ${maxargs} parameters
 $eval_func_interface
 $evalf_func_interface
@@ -451,7 +452,7 @@ function_options::~function_options()
 
 void function_options::initialize(void)
 {
-       set_name("unnamed_function","\\\\operatorname{unnamed}");
+       set_name("unnamed_function","\\\\mbox{unnamed}");
        nparams=0;
        eval_f=evalf_f=derivative_f=series_f=0;
        evalf_params_first=true;
@@ -465,13 +466,19 @@ function_options & function_options::set_name(std::string const & n,
 {
        name=n;
        if (tn==std::string()) {
-               TeX_name="\\\\operatorname{"+name+"}";
+               TeX_name="\\\\mbox{"+name+"}";
        } else {
                TeX_name=tn;
        }
        return *this;
 }
 
+function_options & function_options::latex_name(std::string const & tn)
+{
+       TeX_name=tn;
+       return *this;
+}
+
 // the following lines have been generated for max. ${maxargs} parameters
 $eval_func_implementation
 $evalf_func_implementation
@@ -669,6 +676,9 @@ void function::print(const print_context & c, unsigned level) const
                }
                c.s << ")";
 
+       } else if is_of_type(c, print_latex) {
+               c.s << registered_functions()[serial].TeX_name;
+               printseq(c, '(', ',', ')', exprseq::precedence, function::precedence);
        } else {
                c.s << registered_functions()[serial].name;
                printseq(c, '(', ',', ')', exprseq::precedence, function::precedence);
index fbdceb7..0daa979 100644 (file)
@@ -177,7 +177,8 @@ static ex eta_series(const ex & arg1,
 
 REGISTER_FUNCTION(eta, eval_func(eta_eval).
                        evalf_func(eta_evalf).
-                       series_func(eta_series));
+                       series_func(eta_series).
+                       latex_name("\\eta"));
 
 
 //////////
@@ -315,7 +316,8 @@ static ex Li2_series(const ex &x, const relational &rel, int order, unsigned opt
 REGISTER_FUNCTION(Li2, eval_func(Li2_eval).
                        evalf_func(Li2_evalf).
                        derivative_func(Li2_deriv).
-                       series_func(Li2_series));
+                       series_func(Li2_series).
+                       latex_name("\\mbox{Li}_2"));
 
 //////////
 // trilogarithm
@@ -328,7 +330,8 @@ static ex Li3_eval(const ex & x)
        return Li3(x).hold();
 }
 
-REGISTER_FUNCTION(Li3, eval_func(Li3_eval));
+REGISTER_FUNCTION(Li3, eval_func(Li3_eval).
+                       latex_name("\\mbox{Li}_3"));
 
 //////////
 // factorial
@@ -404,7 +407,8 @@ static ex Order_series(const ex & x, const relational & r, int order, unsigned o
 // Differentiation is handled in function::derivative because of its special requirements
 
 REGISTER_FUNCTION(Order, eval_func(Order_eval).
-                         series_func(Order_series));
+                         series_func(Order_series).
+                         latex_name("\\mathcal{O}"));
 
 //////////
 // Inert partial differentiation operator
index 57dbeb3..014ae93 100644 (file)
@@ -109,7 +109,8 @@ static ex lgamma_series(const ex & arg,
 REGISTER_FUNCTION(lgamma, eval_func(lgamma_eval).
                           evalf_func(lgamma_evalf).
                           derivative_func(lgamma_deriv).
-                          series_func(lgamma_series));
+                          series_func(lgamma_series).
+                          latex_name("\\log \\Gamma"));
 
 
 //////////
@@ -205,7 +206,8 @@ static ex tgamma_series(const ex & arg,
 REGISTER_FUNCTION(tgamma, eval_func(tgamma_eval).
                           evalf_func(tgamma_evalf).
                           derivative_func(tgamma_deriv).
-                          series_func(tgamma_series));
+                          series_func(tgamma_series).
+                          latex_name("\\Gamma"));
 
 
 //////////
@@ -316,7 +318,8 @@ static ex beta_series(const ex & arg1,
 REGISTER_FUNCTION(beta, eval_func(beta_eval).
                         evalf_func(beta_evalf).
                         derivative_func(beta_deriv).
-                        series_func(beta_series));
+                        series_func(beta_series).
+                        latex_name("\\mbox{B}"));
 
 
 //////////
@@ -541,6 +544,7 @@ const unsigned function_index_psi2 =
                               evalf_func(psi2_evalf).
                               derivative_func(psi2_deriv).
                               series_func(psi2_series).
+                           latex_name("\\psi").
                               overloaded(2));
 
 
index dbbb122..3bda254 100644 (file)
@@ -89,7 +89,8 @@ static ex exp_deriv(const ex & x, unsigned deriv_param)
 
 REGISTER_FUNCTION(exp, eval_func(exp_eval).
                        evalf_func(exp_evalf).
-                       derivative_func(exp_deriv));
+                       derivative_func(exp_deriv).
+                       latex_name("\\exp"));
 
 //////////
 // natural logarithm
@@ -210,7 +211,8 @@ static ex log_series(const ex &arg,
 REGISTER_FUNCTION(log, eval_func(log_eval).
                        evalf_func(log_evalf).
                        derivative_func(log_deriv).
-                       series_func(log_series));
+                       series_func(log_series).
+                       latex_name("\\ln"));
 
 //////////
 // sine (trigonometric function)
@@ -291,7 +293,8 @@ static ex sin_deriv(const ex & x, unsigned deriv_param)
 
 REGISTER_FUNCTION(sin, eval_func(sin_eval).
                        evalf_func(sin_evalf).
-                       derivative_func(sin_deriv));
+                       derivative_func(sin_deriv).
+                       latex_name("\\sin"));
 
 //////////
 // cosine (trigonometric function)
@@ -372,7 +375,8 @@ static ex cos_deriv(const ex & x, unsigned deriv_param)
 
 REGISTER_FUNCTION(cos, eval_func(cos_eval).
                        evalf_func(cos_evalf).
-                       derivative_func(cos_deriv));
+                       derivative_func(cos_deriv).
+                       latex_name("\\cos"));
 
 //////////
 // tangent (trigonometric function)
@@ -467,7 +471,8 @@ static ex tan_series(const ex &x,
 REGISTER_FUNCTION(tan, eval_func(tan_eval).
                        evalf_func(tan_evalf).
                        derivative_func(tan_deriv).
-                       series_func(tan_series));
+                       series_func(tan_series).
+                       latex_name("\\tan"));
 
 //////////
 // inverse sine (arc sine)
@@ -518,7 +523,8 @@ static ex asin_deriv(const ex & x, unsigned deriv_param)
 
 REGISTER_FUNCTION(asin, eval_func(asin_eval).
                         evalf_func(asin_evalf).
-                        derivative_func(asin_deriv));
+                        derivative_func(asin_deriv).
+                        latex_name("\\arcsin"));
 
 //////////
 // inverse cosine (arc cosine)
@@ -569,7 +575,8 @@ static ex acos_deriv(const ex & x, unsigned deriv_param)
 
 REGISTER_FUNCTION(acos, eval_func(acos_eval).
                         evalf_func(acos_evalf).
-                        derivative_func(acos_deriv));
+                        derivative_func(acos_deriv).
+                        latex_name("\\arccos"));
 
 //////////
 // inverse tangent (arc tangent)
@@ -660,7 +667,8 @@ static ex atan_series(const ex &arg,
 REGISTER_FUNCTION(atan, eval_func(atan_eval).
                         evalf_func(atan_evalf).
                         derivative_func(atan_deriv).
-                        series_func(atan_series));
+                        series_func(atan_series).
+                        latex_name("\\arctan"));
 
 //////////
 // inverse tangent (atan2(y,x))
@@ -754,7 +762,8 @@ static ex sinh_deriv(const ex & x, unsigned deriv_param)
 
 REGISTER_FUNCTION(sinh, eval_func(sinh_eval).
                         evalf_func(sinh_evalf).
-                        derivative_func(sinh_deriv));
+                        derivative_func(sinh_deriv).
+                        latex_name("\\sinh"));
 
 //////////
 // hyperbolic cosine (trigonometric function)
@@ -808,8 +817,8 @@ static ex cosh_deriv(const ex & x, unsigned deriv_param)
 
 REGISTER_FUNCTION(cosh, eval_func(cosh_eval).
                         evalf_func(cosh_evalf).
-                        derivative_func(cosh_deriv));
-
+                        derivative_func(cosh_deriv).
+                        latex_name("\\cosh"));
 
 //////////
 // hyperbolic tangent (trigonometric function)
@@ -880,7 +889,8 @@ static ex tanh_series(const ex &x,
 REGISTER_FUNCTION(tanh, eval_func(tanh_eval).
                         evalf_func(tanh_evalf).
                         derivative_func(tanh_deriv).
-                        series_func(tanh_series));
+                        series_func(tanh_series).
+                        latex_name("\\tanh"));
 
 //////////
 // inverse hyperbolic sine (trigonometric function)
index 0f06908..0b3046e 100644 (file)
@@ -83,6 +83,7 @@ const unsigned function_index_zeta1 =
                               eval_func(zeta1_eval).
                               evalf_func(zeta1_evalf).
                               derivative_func(zeta1_deriv).
+                           latex_name("\\zeta").
                               overloaded(2));
 
 //////////
index b42fcfe..27451f6 100644 (file)
@@ -136,8 +136,7 @@ void mul::print(const print_context & c, unsigned level) const
 
        } else if (is_of_type(c, print_csrc)) {
 
-               if (precedence <= level)
-                       c.s << "(";
+               c.s << "(";
 
                if (!overall_coeff.is_equal(_ex1())) {
                        overall_coeff.bp->print(c, precedence);
@@ -179,8 +178,12 @@ void mul::print(const print_context & c, unsigned level) const
 
        } else {
 
-               if (precedence <= level)
-                       c.s << "(";
+               if (precedence <= level) {
+                       if (is_of_type(c, print_latex))
+                               c.s << "{(";
+                       else
+                               c.s << "(";
+               }
 
                bool first = true;
 
@@ -201,14 +204,20 @@ void mul::print(const print_context & c, unsigned level) const
                                else
                                        coeff.print(c, precedence);
                        }
-                       c.s << '*';
+                       if (is_of_type(c, print_latex))
+                               c.s << ' ';
+                       else
+                               c.s << '*';
                }
 
                // Then proceed with the remaining factors
                epvector::const_iterator it = seq.begin(), itend = seq.end();
                while (it != itend) {
                        if (!first) {
-                               c.s << '*';
+                               if (is_of_type(c, print_latex))
+                                       c.s << ' ';
+                               else
+                                       c.s << '*';
                        } else {
                                first = false;
                        }
@@ -216,8 +225,12 @@ void mul::print(const print_context & c, unsigned level) const
                        it++;
                }
 
-               if (precedence <= level)
-                       c.s << ")";
+               if (precedence <= level) {
+                       if (is_of_type(c, print_latex))
+                               c.s << ")}";
+                       else
+                               c.s << ")";
+               }
        }
 }
 
index 1308c9e..3af060d 100644 (file)
@@ -410,15 +410,18 @@ void numeric::print(const print_context & c, unsigned level) const
                c.s.flags(oldflags);
 
        } else {
-
-               cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
-               cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
+               const std::string par_open  = is_of_type(c, print_latex) ? "{(" : "(";
+               const std::string par_close = is_of_type(c, print_latex) ? ")}" : ")";
+               const std::string imag_sym  = is_of_type(c, print_latex) ? "i" : "I";
+               const std::string mul_sym   = is_of_type(c, print_latex) ? " " : "*";
+               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 (cln::zerop(i)) {
                        // case 1, real:  x  or  -x
                        if ((precedence <= level) && (!this->is_nonneg_integer())) {
-                               c.s << "(";
+                               c.s << par_open;
                                print_real_number(c.s, r);
-                               c.s << ")";
+                               c.s << par_close;
                        } else {
                                print_real_number(c.s, r);
                        }
@@ -427,47 +430,47 @@ void numeric::print(const print_context & c, unsigned level) const
                                // case 2, imaginary:  y*I  or  -y*I
                                if ((precedence <= level) && (i < 0)) {
                                        if (i == -1) {
-                                               c.s << "(-I)";
+                                               c.s << par_open+imag_sym+par_close;
                                        } else {
-                                               c.s << "(";
+                                               c.s << par_open;
                                                print_real_number(c.s, i);
-                                               c.s << "*I)";
+                                               c.s << mul_sym+imag_sym+par_close;
                                        }
                                } else {
                                        if (i == 1) {
-                                               c.s << "I";
+                                               c.s << imag_sym;
                                        } else {
                                                if (i == -1) {
-                                                       c.s << "-I";
+                                                       c.s << "-" << imag_sym;
                                                } else {
                                                        print_real_number(c.s, i);
-                                                       c.s << "*I";
+                                                       c.s << mul_sym+imag_sym;
                                                }
                                        }
                                }
                        } else {
                                // case 3, complex:  x+y*I  or  x-y*I  or  -x+y*I  or  -x-y*I
                                if (precedence <= level)
-                                       c.s << "(";
+                                       c.s << par_open;
                                print_real_number(c.s, r);
                                if (i < 0) {
                                        if (i == -1) {
-                                               c.s << "-I";
+                                               c.s << "-"+imag_sym;
                                        } else {
                                                print_real_number(c.s, i);
-                                               c.s << "*I";
+                                               c.s << mul_sym+imag_sym;
                                        }
                                } else {
                                        if (i == 1) {
-                                               c.s << "+I";
+                                               c.s << "+"+imag_sym;
                                        } else {
                                                c.s << "+";
                                                print_real_number(c.s, i);
-                                               c.s << "*I";
+                                               c.s << mul_sym+imag_sym;
                                        }
                                }
                                if (precedence <= level)
-                                       c.s << ")";
+                                       c.s << par_close;
                        }
                }
        }
index 109eacf..6b8c184 100644 (file)
@@ -177,17 +177,31 @@ void power::print(const print_context & c, unsigned level) const
        } else {
 
                if (exponent.is_equal(_ex1_2())) {
-                       c.s << "sqrt(";
+                       if (is_of_type(c, print_latex))
+                               c.s << "\\sqrt{";
+                       else
+                               c.s << "sqrt(";
                        basis.print(c);
-                       c.s << ")";
+                       if (is_of_type(c, print_latex))
+                               c.s << "}";
+                       else
+                               c.s << ")";
                } else {
-                       if (precedence <= level)
-                               c.s << "(";
+                       if (precedence <= level) {
+                               if (is_of_type(c, print_latex))
+                                       c.s << "{(";
+                               else
+                                       c.s << "(";
+                       }
                        basis.print(c, precedence);
                        c.s << "^";
                        exponent.print(c, precedence);
-                       if (precedence <= level)
-                               c.s << ")";
+                       if (precedence <= level) {
+                               if (is_of_type(c, print_latex))
+                                       c.s << ")}";
+                               else
+                                       c.s << ")";
+                       }
                }
        }
 }
index 4fdbeb8..c8bd9b6 100644 (file)
@@ -39,6 +39,14 @@ public:
        virtual void dummy(void) {}
 };
 
+/** Context for latex-parsable output. */
+class print_latex : public print_context
+{
+public:
+       print_latex(std::ostream & os = std::cout)
+         : print_context(os) {}
+};
+
 /** Context for tree-like output for debugging. */
 class print_tree : public print_context
 {
index 789d767..5f15a2e 100644 (file)
@@ -144,7 +144,10 @@ void pseries::print(const print_context & c, unsigned level) const
 
                if (precedence <= level)
                        c.s << "(";
-
+               
+               std::string par_open = is_of_type(c, print_latex) ? "{(" : "(";
+               std::string par_close = is_of_type(c, print_latex) ? ")}" : ")";
+               
                // objects of type pseries must not have any zero entries, so the
                // trivial (zero) pseries needs a special treatment here:
                if (seq.size() == 0)
@@ -159,27 +162,33 @@ void pseries::print(const print_context & c, unsigned level) const
                                        i->rest.info(info_flags::positive)) {
                                        i->rest.print(c);
                                } else {
-                                       c.s << '(';
+                                       c.s << par_open;
                                        i->rest.print(c);
-                                       c.s << ')';
+                                       c.s << par_close;
                                }
                                // print 'coeff', something like (x-1)^42
                                if (!i->coeff.is_zero()) {
                                        c.s << '*';
                                        if (!point.is_zero()) {
-                                               c.s << '(';
+                                               c.s << par_open;
                                                (var-point).print(c);
-                                               c.s << ')';
+                                               c.s << par_close;
                                        } else
                                                var.print(c);
                                        if (i->coeff.compare(_ex1())) {
                                                c.s << '^';
                                                if (i->coeff.info(info_flags::negative)) {
-                                                       c.s << '(';
-                                                       i->coeff.print(c);
-                                                       c.s << ')';
-                                               } else
+                                                       c.s << par_open;
                                                        i->coeff.print(c);
+                                                       c.s << par_close;
+                                               } else {
+                                                       if (is_of_type(c, print_latex)) {
+                                                               c.s << '{';
+                                                               i->coeff.print(c);
+                                                               c.s << '}';
+                                                       } else
+                                                               i->coeff.print(c);
+                                               }
                                        }
                                }
                        } else
index e093e6c..bebb877 100644 (file)
@@ -143,6 +143,24 @@ void symbol::print(const print_context & c, unsigned level) const
                    << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
                    << std::endl;
 
+       } else if (is_of_type(c, print_latex)) {
+               if (name=="alpha"        || name=="beta"         || name=="gamma"
+                || name=="delta"        || name=="epsilon"      || name=="varepsilon"
+                || name=="zeta"         || name=="eta"          || name=="theta"
+                || name=="vartheta"     || name=="iota"         || name=="kappa"
+                || name=="lambda"       || name=="mu"           || name=="nu"
+                || name=="xi"           || name=="omicron"      || name=="pi"
+                || name=="varpi"        || name=="rho"          || name=="varrho"
+                || name=="sigma"        || name=="varsigma"     || name=="tau"
+                || name=="upsilon"      || name=="phi"          || name=="varphix"
+                || name=="chi"          || name=="psi"          || name=="omega"
+                || name=="Gamma"        || name=="Delta"        || name=="Theta"
+                || name=="Lambda"       || name=="Xi"           || name=="Pi"
+                || name=="Sigma"        || name=="Upsilon"      || name=="Phi"
+                || name=="Psi"          || name=="Omega")
+                       c.s << "\\" << name;
+               else
+                       c.s << name;
        } else
                c.s << name;
 }