Added complex conjugation methods and GiNaC function "conjugate".
authorJens Vollinga <vollinga@thep.physik.uni-mainz.de>
Sun, 4 Jan 2004 16:11:45 +0000 (16:11 +0000)
committerJens Vollinga <vollinga@thep.physik.uni-mainz.de>
Sun, 4 Jan 2004 16:11:45 +0000 (16:11 +0000)
25 files changed:
ginac/basic.cpp
ginac/basic.h
ginac/clifford.cpp
ginac/clifford.h
ginac/container.h
ginac/ex.h
ginac/expair.cpp
ginac/expair.h
ginac/expairseq.cpp
ginac/expairseq.h
ginac/flags.h
ginac/function.pl
ginac/idx.h
ginac/inifcns.cpp
ginac/inifcns.h
ginac/matrix.cpp
ginac/matrix.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/pseries.h
ginac/symbol.cpp
ginac/symbol.h

index 01a2901..038cd7b 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's ABC. */
 
 /*
- *  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
@@ -674,6 +674,11 @@ exvector basic::get_free_indices() const
        return exvector(); // return an empty exvector
 }
 
+ex basic::conjugate() const
+{
+       return *this;
+}
+
 ex basic::eval_ncmul(const exvector & v) const
 {
        return hold_ncmul(v);
index 12a958c..da634e0 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to GiNaC's ABC. */
 
 /*
- *  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
@@ -182,7 +182,11 @@ public:
        virtual unsigned return_type() const;
        virtual unsigned return_type_tinfo() const;
 
-protected: // functions that should be called from class ex only
+       // complex conjugation
+       virtual ex conjugate() const;
+
+       // functions that should be called from class ex only
+protected:
        virtual int compare_same_type(const basic & other) const;
        virtual bool is_equal_same_type(const basic & other) const;
 
index 7d4596d..679def3 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's clifford algebra (Dirac gamma) objects. */
 
 /*
- *  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
@@ -484,6 +484,21 @@ ex clifford::thiscontainer(std::auto_ptr<exvector> vp) const
        return clifford(representation_label, vp);
 }
 
+ex diracgamma5::conjugate() const
+{      
+       return _ex_1 * (*this);
+}
+
+ex diracgammaL::conjugate() const
+{
+       return (new diracgammaR)->setflag(status_flags::dynallocated);
+}
+
+ex diracgammaR::conjugate() const
+{
+       return (new diracgammaL)->setflag(status_flags::dynallocated);
+}
+
 //////////
 // global functions
 //////////
index d777079..7d6cc80 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to GiNaC's clifford algebra (Dirac gamma) objects. */
 
 /*
- *  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
@@ -104,6 +104,9 @@ class diracgamma5 : public tensor
 {
        GINAC_DECLARE_REGISTERED_CLASS(diracgamma5, tensor)
 
+       // functions overriding virtual functions from base classes
+       ex conjugate() const;
+
        // non-virtual functions in this class
 protected:
        void do_print(const print_context & c, unsigned level) const;
@@ -117,6 +120,9 @@ class diracgammaL : public tensor
 {
        GINAC_DECLARE_REGISTERED_CLASS(diracgammaL, tensor)
 
+       // functions overriding virtual functions from base classes
+       ex conjugate() const;
+
        // non-virtual functions in this class
 protected:
        void do_print(const print_context & c, unsigned level) const;
@@ -130,6 +136,9 @@ class diracgammaR : public tensor
 {
        GINAC_DECLARE_REGISTERED_CLASS(diracgammaR, tensor)
 
+       // functions overriding virtual functions from base classes
+       ex conjugate() const;
+
        // non-virtual functions in this class
 protected:
        void do_print(const print_context & c, unsigned level) const;
index 2459b36..5d6fe3a 100644 (file)
@@ -3,7 +3,7 @@
  *  Wrapper template for making GiNaC classes out of STL containers. */
 
 /*
- *  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
@@ -124,7 +124,6 @@ private:
        STLT & stlt;
 };
 
-
 /** Wrapper template for making GiNaC classes out of STL containers. */
 template <template <class> class C>
 class container : public basic, public container_storage<C> {
@@ -368,6 +367,32 @@ public:
        ex subs(const exmap & m, unsigned options = 0) const;
 
 protected:
+       ex conjugate() const
+       {
+               STLT* newcont = 0;
+               for (const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+                       if (newcont) {
+                               newcont->push_back(i->conjugate());
+                               continue;
+                       }
+                       ex x = i->conjugate();
+                       if (are_ex_trivially_equal(x, *i)) {
+                               continue;
+                       }
+                       newcont = new STLT;
+                       reserve (*newcont, seq.size());
+                       for (const_iterator j=seq.begin(); j!=i; ++j) {
+                               newcont->push_back(*j);
+                       }
+                       newcont->push_back(x);
+               }
+               if (newcont) {
+                       ex result = thiscontainer(*newcont);
+                       delete newcont;
+                       return result;
+               }
+               return *this;
+       }
        bool is_equal_same_type(const basic & other) const;
 
        // new virtual functions which can be overridden by derived classes
index 2447c3f..95115a3 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to GiNaC's light-weight expression handles. */
 
 /*
- *  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
@@ -132,6 +132,9 @@ public:
        ex lhs() const;
        ex rhs() const;
 
+       // complex conjugation
+       ex conjugate() const { return bp->conjugate(); }
+
        // pattern matching
        bool has(const ex & pattern) const { return bp->has(pattern); }
        bool find(const ex & pattern, lst & found) const;
index 9d8375d..6070ffb 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of expression pairs (building blocks of expairseq). */
 
 /*
- *  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
@@ -23,6 +23,7 @@
 #include <iostream>
 
 #include "expair.h"
+#include "operators.h"
 
 namespace GiNaC {
 
@@ -34,4 +35,14 @@ void expair::print(std::ostream & os) const
        coeff.print(c, c.delta_indent);
 }
 
+const expair expair::conjugate() const
+{
+       ex newrest = rest.conjugate();
+       ex newcoeff = coeff.conjugate();
+       if (are_ex_trivially_equal(newrest,rest) && are_ex_trivially_equal(newcoeff,coeff)) {
+               return *this;
+       }
+       return expair(newrest, newcoeff);
+}
+
 } // namespace GiNaC
index 2610e8f..ce17c8d 100644 (file)
@@ -3,7 +3,7 @@
  *  Definition of expression pairs (building blocks of expairseq). */
 
 /*
- *  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
@@ -84,7 +84,9 @@ public:
                rest.swap(other.rest);
                coeff.swap(other.coeff);
        }
-       
+
+       const expair conjugate() const;
+
        ex rest;    ///< first member of pair, an arbitrary expression
        ex coeff;   ///< second member of pair, must be numeric
 };
index 88f195c..676011a 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of sequences of expression pairs. */
 
 /*
- *  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
@@ -310,6 +310,42 @@ ex expairseq::eval(int level) const
        return (new expairseq(vp, overall_coeff))->setflag(status_flags::dynallocated | status_flags::evaluated);
 }
 
+epvector* conjugateepvector(const epvector&epv)
+{
+       epvector *newepv = 0;
+       for (epvector::const_iterator i=epv.begin(); i!=epv.end(); ++i) {
+               if(newepv) {
+                       newepv->push_back(i->conjugate());
+                       continue;
+               }
+               expair x = i->conjugate();
+               if (x.is_equal(*i)) {
+                       continue;
+               }
+               newepv = new epvector;
+               newepv->reserve(epv.size());
+               for (epvector::const_iterator j=epv.begin(); j!=i; ++j) {
+                       newepv->push_back(*j);
+               }
+               newepv->push_back(x);
+       }
+       return newepv;
+}
+
+ex expairseq::conjugate() const
+{
+       epvector* newepv = conjugateepvector(seq);
+       ex x = overall_coeff.conjugate();
+       if (!newepv && are_ex_trivially_equal(x, overall_coeff)) {
+               return *this;
+       }
+       ex result = thisexpairseq(newepv ? *newepv : seq, x);
+       if (newepv) {
+               delete newepv;
+       }
+       return result;
+}
+
 bool expairseq::match(const ex & pattern, lst & repl_lst) const
 {
        // This differs from basic::match() because we want "a+b+c+d" to
index 96666b8..c0f4c33 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to sequences of expression pairs. */
 
 /*
- *  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
@@ -49,6 +49,10 @@ typedef epvector::iterator epp;             ///< expair-vector pointer
 typedef std::list<epp> epplist;             ///< list of expair-vector pointers
 typedef std::vector<epplist> epplistvector; ///< vector of epplist
 
+/** Complex conjugate every element of an epvector. Returns zero if this
+ *  does not change anything. */
+epvector* conjugateepvector(const epvector&);
+
 /** A sequence of class expair.
  *  This is used for time-critical classes like sums and products of terms
  *  since handling a list of coeff and rest is much faster than handling a
@@ -81,6 +85,7 @@ public:
        ex to_polynomial(exmap & repl) const;
        bool match(const ex & pattern, lst & repl_lst) const;
        ex subs(const exmap & m, unsigned options = 0) const;
+       ex conjugate() const;
 protected:
        bool is_equal_same_type(const basic & other) const;
        unsigned return_type() const;
index ef92160..616cc56 100644 (file)
@@ -3,7 +3,7 @@
  *  Collection of all flags used through the GiNaC framework. */
 
 /*
- *  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
@@ -47,6 +47,17 @@ public:
        };
 };
 
+/** Flags to decide how conjugate should treat a symbol */
+class symbol_options {
+public:
+       enum {
+               /** Symbol is treated like a complex valued expression */
+               complex,
+               /** Symbol is treated like a real valued expression */
+               real
+       };
+};
+
 /** Flags to control series expansion. */
 class series_options {
 public:
index 102e324..6b25c70 100755 (executable)
@@ -1,3 +1,23 @@
+#  This perl script automatically generates function.h and function.cpp
+
+#  function.pl options: \$maxargs=${maxargs}
+# 
+#  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
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+# 
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+# 
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
 $maxargs=14;
 
 sub generate_seq {
@@ -54,6 +74,10 @@ $typedef_evalf_funcp=generate(
 'typedef ex (* evalf_funcp_${N})(${SEQ1});'."\n",
 'const ex &','','');
 
+$typedef_conjugate_funcp=generate(
+'typedef ex (* conjugate_funcp_${N})(${SEQ1});'."\n",
+'const ex &','','');
+
 $typedef_derivative_funcp=generate(
 'typedef ex (* derivative_funcp_${N})(${SEQ1}, unsigned);'."\n",
 'const ex &','','');
@@ -70,6 +94,8 @@ $eval_func_interface=generate('    function_options & eval_func(eval_funcp_${N}
 
 $evalf_func_interface=generate('    function_options & evalf_func(evalf_funcp_${N} ef);'."\n",'','','');
 
+$conjugate_func_interface=generate('    function_options & conjugate_func(conjugate_funcp_${N} d);'."\n",'','','');
+
 $derivative_func_interface=generate('    function_options & derivative_func(derivative_funcp_${N} d);'."\n",'','','');
 
 $series_func_interface=generate('    function_options & series_func(series_funcp_${N} s);'."\n",'','','');
@@ -110,6 +136,12 @@ $evalf_switch_statement=generate(
                return ((evalf_funcp_${N})(opt.evalf_f))(${SEQ1});
 END_OF_EVALF_SWITCH_STATEMENT
 
+$conjugate_switch_statement=generate(
+       <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','','');
+       case ${N}:
+               return ((conjugate_funcp_${N})(opt.conjugate_f))(${SEQ1});
+END_OF_DIFF_SWITCH_STATEMENT
+
 $diff_switch_statement=generate(
        <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','','');
        case ${N}:
@@ -154,6 +186,16 @@ function_options & function_options::evalf_func(evalf_funcp_${N} ef)
 }
 END_OF_EVALF_FUNC_IMPLEMENTATION
 
+$conjugate_func_implementation=generate(
+       <<'END_OF_CONJUGATE_FUNC_IMPLEMENTATION','','','');
+function_options & function_options::conjugate_func(conjugate_funcp_${N} c)
+{
+       test_and_set_nparams(${N});
+       conjugate_f = conjugate_funcp(c);
+       return *this;
+}
+END_OF_CONJUGATE_FUNC_IMPLEMENTATION
+
 $derivative_func_implementation=generate(
        <<'END_OF_DERIVATIVE_FUNC_IMPLEMENTATION','','','');
 function_options & function_options::derivative_func(derivative_funcp_${N} d)
@@ -184,7 +226,7 @@ $interface=<<END_OF_INTERFACE;
  *  Please do not modify it directly, edit the perl script instead!
  *  function.pl options: \$maxargs=${maxargs}
  *
- *  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
@@ -227,6 +269,7 @@ class symmetry;
 
 typedef ex (* eval_funcp)();
 typedef ex (* evalf_funcp)();
+typedef ex (* conjugate_funcp)();
 typedef ex (* derivative_funcp)();
 typedef ex (* series_funcp)();
 typedef void (* print_funcp)();
@@ -234,6 +277,7 @@ typedef void (* print_funcp)();
 // the following lines have been generated for max. ${maxargs} parameters
 $typedef_eval_funcp
 $typedef_evalf_funcp
+$typedef_conjugate_funcp
 $typedef_derivative_funcp
 $typedef_series_funcp
 $typedef_print_funcp
@@ -243,6 +287,7 @@ $typedef_print_funcp
 // of individual ex objects.  Then, the number of arguments is not limited.
 typedef ex (* eval_funcp_exvector)(const exvector &);
 typedef ex (* evalf_funcp_exvector)(const exvector &);
+typedef ex (* conjugate_funcp_exvector)(const exvector &);
 typedef ex (* derivative_funcp_exvector)(const exvector &, unsigned);
 typedef ex (* series_funcp_exvector)(const exvector &, const relational &, int, unsigned);
 typedef void (* print_funcp_exvector)(const exvector &, const print_context &);
@@ -264,12 +309,14 @@ public:
 // the following lines have been generated for max. ${maxargs} parameters
 $eval_func_interface
 $evalf_func_interface
+$conjugate_func_interface
 $derivative_func_interface
 $series_func_interface
 $print_func_interface
 // end of generated lines
        function_options & eval_func(eval_funcp_exvector e);
        function_options & evalf_func(evalf_funcp_exvector ef);
+       function_options & conjugate_func(conjugate_funcp_exvector d);
        function_options & derivative_func(derivative_funcp_exvector d);
        function_options & series_func(series_funcp_exvector s);
 
@@ -302,6 +349,7 @@ protected:
 
        eval_funcp eval_f;
        evalf_funcp evalf_f;
+       conjugate_funcp conjugate_f;
        derivative_funcp derivative_f;
        series_funcp series_f;
        std::vector<print_funcp> print_dispatch_table;
@@ -319,6 +367,7 @@ protected:
 
        bool eval_use_exvector_args;
        bool evalf_use_exvector_args;
+       bool conjugate_use_exvector_args;
        bool derivative_use_exvector_args;
        bool series_use_exvector_args;
        bool print_use_exvector_args;
@@ -372,6 +421,7 @@ public:
        ex series(const relational & r, int order, unsigned options = 0) const;
        ex thiscontainer(const exvector & v) const;
        ex thiscontainer(std::auto_ptr<exvector> vp) const;
+       ex conjugate() const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
@@ -435,7 +485,7 @@ $implementation=<<END_OF_IMPLEMENTATION;
  *  Please do not modify it directly, edit the perl script instead!
  *  function.pl options: \$maxargs=${maxargs}
  *
- *  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
@@ -496,11 +546,12 @@ void function_options::initialize()
 {
        set_name("unnamed_function", "\\\\mbox{unnamed}");
        nparams = 0;
-       eval_f = evalf_f = derivative_f = series_f = 0;
+       eval_f = evalf_f = conjugate_f = derivative_f = series_f = 0;
        evalf_params_first = true;
        use_return_type = false;
        eval_use_exvector_args = false;
        evalf_use_exvector_args = false;
+       conjugate_use_exvector_args = false;
        derivative_use_exvector_args = false;
        series_use_exvector_args = false;
        print_use_exvector_args = false;
@@ -529,6 +580,7 @@ function_options & function_options::latex_name(std::string const & tn)
 // the following lines have been generated for max. ${maxargs} parameters
 $eval_func_implementation
 $evalf_func_implementation
+$conjugate_func_implementation
 $derivative_func_implementation
 $series_func_implementation
 // end of generated lines
@@ -545,6 +597,12 @@ function_options& function_options::evalf_func(evalf_funcp_exvector ef)
        evalf_f = evalf_funcp(ef);
        return *this;
 }
+function_options& function_options::conjugate_func(conjugate_funcp_exvector c)
+{
+       conjugate_use_exvector_args = true;
+       conjugate_f = conjugate_funcp(c);
+       return *this;
+}
 function_options& function_options::derivative_func(derivative_funcp_exvector d)
 {
        derivative_use_exvector_args = true;
@@ -926,6 +984,28 @@ ${series_switch_statement}
        throw(std::logic_error("function::series(): invalid nparams"));
 }
 
+/** Implementation of ex::conjugate for functions. */
+ex function::conjugate() const
+{
+       GINAC_ASSERT(serial<registered_functions().size());
+       const function_options & opt = registered_functions()[serial];
+
+       if (opt.conjugate_f==0) {
+               return exprseq::conjugate();
+       }
+
+       if (opt.conjugate_use_exvector_args) {
+               return ((conjugate_funcp_exvector)(opt.conjugate_f))(seq);
+       }
+
+       switch (opt.nparams) {
+               // the following lines have been generated for max. ${maxargs} parameters
+${conjugate_switch_statement}
+               // end of generated lines
+       }
+       throw(std::logic_error("function::conjugate(): invalid nparams"));
+}
+
 // protected
 
 /** Implementation of ex::diff() for functions. It applies the chain rule,
index 13004fd..97538d7 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to GiNaC's indices. */
 
 /*
- *  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
@@ -172,6 +172,8 @@ public:
        // functions overriding virtual functions from base classes
 public:
        bool is_dummy_pair_same_type(const basic & other) const;
+       // complex conjugation
+       ex conjugate() const { return toggle_dot(); }
 
 protected:
        bool match_same_type(const basic & other) const;
index 443022a..33582ac 100644 (file)
@@ -3,7 +3,7 @@
  *  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(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, eval_func(conjugate_eval).
+                       evalf_func(conjugate_evalf).
+                       print_func<print_latex>(conjugate_print_latex).
+                       conjugate_func(conjugate_conjugate));
+
 //////////
 // absolute value
 //////////
@@ -69,11 +101,17 @@ static void abs_print_csrc_float(const ex & arg, const print_context & c)
        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));
 
 
 //////////
@@ -133,9 +171,15 @@ static ex csgn_series(const ex & arg,
        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));
 
 
 //////////
@@ -210,11 +254,17 @@ static ex eta_series(const ex & x, const ex & y,
        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));
 
 
 //////////
@@ -416,8 +466,14 @@ static ex factorial_eval(const ex & x)
                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
@@ -436,8 +492,17 @@ static ex binomial_eval(const ex & x, const ex &y)
                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)
@@ -470,11 +535,17 @@ static ex Order_series(const ex & x, const relational & r, int order, unsigned o
        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
index 412eed5..19a66d3 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to 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
@@ -28,6 +28,9 @@
 
 namespace GiNaC {
 
+/** Complex conjugate. */
+DECLARE_FUNCTION_1P(conjugate)
+       
 /** Absolute value. */
 DECLARE_FUNCTION_1P(abs)
        
index 2c191ff..a6f3ca9 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of symbolic matrices */
 
 /*
- *  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
@@ -234,6 +234,34 @@ ex matrix::subs(const exmap & mp, unsigned options) const
        return matrix(row, col, m2).subs_one_level(mp, options);
 }
 
+/** Complex conjugate every matrix entry. */
+ex matrix::conjugate() const
+{
+       exvector * ev = 0;
+       for (exvector::const_iterator i=m.begin(); i!=m.end(); ++i) {
+               ex x = i->conjugate();
+               if (ev) {
+                       ev->push_back(x);
+                       continue;
+               }
+               if (are_ex_trivially_equal(x, *i)) {
+                       continue;
+               }
+               ev = new exvector;
+               ev->reserve(m.size());
+               for (exvector::const_iterator j=m.begin(); j!=i; ++j) {
+                       ev->push_back(*j);
+               }
+               ev->push_back(x);
+       }
+       if (ev) {
+               ex result = matrix(row, col, *ev);
+               delete ev;
+               return result;
+       }
+       return *this;
+}
+
 // protected
 
 int matrix::compare_same_type(const basic & other) const
index fc6a80b..ee30601 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to symbolic matrices */
 
 /*
- *  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
@@ -120,6 +120,7 @@ public:
        ex add_indexed(const ex & self, const ex & other) const;
        ex scalar_mul_indexed(const ex & self, const numeric & other) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
+       ex conjugate() const;
 
 protected:
        bool match_same_type(const basic & other) const;
index e3a6b55..a00bff1 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's non-commutative products of expressions. */
 
 /*
- *  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
@@ -456,6 +456,25 @@ ex ncmul::thiscontainer(std::auto_ptr<exvector> vp) const
        return (new ncmul(vp))->setflag(status_flags::dynallocated);
 }
 
+ex ncmul::conjugate() const
+{
+       if (return_type() != return_types::noncommutative) {
+               return exprseq::conjugate();
+       }
+
+       if (return_type_tinfo() & 0xffffff00U != TINFO_clifford) {
+               return exprseq::conjugate();
+       }
+
+       exvector ev;
+       ev.reserve(nops());
+       for (const_iterator i=end(); i!=begin();) {
+               --i;
+               ev.push_back(i->conjugate());
+       }
+       return (new ncmul(ev, true))->setflag(status_flags::dynallocated).eval();
+}
+
 // protected
 
 /** Implementation of ex::diff() for a non-commutative product. It applies
index 0139a63..46a7aae 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to GiNaC's non-commutative products of expressions. */
 
 /*
- *  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
@@ -64,6 +64,7 @@ public:
        exvector get_free_indices() const;
        ex thiscontainer(const exvector & v) const;
        ex thiscontainer(std::auto_ptr<exvector> vp) const;
+       ex conjugate() const;
 
 protected:
        ex derivative(const symbol & s) const;
index fe18097..aa0b082 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's symbolic exponentiation (basis^exponent). */
 
 /*
- *  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
@@ -558,6 +558,16 @@ ex power::eval_ncmul(const exvector & v) const
        return inherited::eval_ncmul(v);
 }
 
+ex power::conjugate() const
+{
+       ex newbasis = basis.conjugate();
+       ex newexponent = exponent.conjugate();
+       if (are_ex_trivially_equal(basis, newbasis) && are_ex_trivially_equal(exponent, newexponent)) {
+               return *this;
+       }
+       return (new power(newbasis, newexponent))->setflag(status_flags::dynallocated);
+}
+
 // protected
 
 /** Implementation of ex::diff() for a power.
index eddcf2f..286ee81 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to GiNaC's symbolic exponentiation (basis^exponent). */
 
 /*
- *  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
@@ -65,6 +65,7 @@ public:
        ex to_rational(exmap & repl) const;
        ex to_polynomial(exmap & repl) const;
        exvector get_free_indices() const;
+       ex conjugate() const;
 protected:
        ex derivative(const symbol & s) const;
        ex eval_ncmul(const exvector & v) const;
index a99725e..3528cbb 100644 (file)
@@ -4,7 +4,7 @@
  *  methods for series expansion. */
 
 /*
- *  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
@@ -407,6 +407,23 @@ ex pseries::evalf(int level) const
        return (new pseries(relational(var,point), new_seq))->setflag(status_flags::dynallocated | status_flags::evaluated);
 }
 
+ex pseries::conjugate() const
+{
+       epvector * newseq = conjugateepvector(seq);
+       ex newvar = var.conjugate();
+       ex newpoint = point.conjugate();
+
+       if (!newseq     && are_ex_trivially_equal(newvar, var) && are_ex_trivially_equal(point, newpoint)) {
+               return *this;
+       }
+
+       ex result = (new pseries(newvar==newpoint, newseq ? *newseq : seq))->setflag(status_flags::dynallocated);
+       if (newseq) {
+               delete newseq;
+       }
+       return result;
+}
+
 ex pseries::subs(const exmap & m, unsigned options) const
 {
        // If expansion variable is being substituted, convert the series to a
index 823c5ba..fd2a042 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to class for extended truncated power series. */
 
 /*
- *  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
@@ -55,6 +55,7 @@ public:
        ex subs(const exmap & m, unsigned options = 0) const;
        ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const;
        ex expand(unsigned options = 0) const;
+       ex conjugate() const;
 protected:
        ex derivative(const symbol & s) const;
 
index 480c25c..57227fd 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's symbolic objects. */
 
 /*
- *  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
@@ -28,6 +28,7 @@
 #include "archive.h"
 #include "tostring.h"
 #include "utils.h"
+#include "inifcns.h"
 
 namespace GiNaC {
 
@@ -42,7 +43,7 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(symbol, basic,
 //////////
 
 symbol::symbol()
- : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(autoname_prefix() + ToString(serial)), TeX_name(name), ret_type(return_types::commutative), ret_type_tinfo(TINFO_symbol)
+ : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(autoname_prefix() + ToString(serial)), TeX_name(name), ret_type(return_types::commutative), ret_type_tinfo(TINFO_symbol), domain(symbol_options::complex)
 {
        setflag(status_flags::evaluated | status_flags::expanded);
 }
@@ -53,26 +54,26 @@ symbol::symbol()
 
 // public
 
-symbol::symbol(const std::string & initname)
- : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(default_TeX_name()), ret_type(return_types::commutative), ret_type_tinfo(TINFO_symbol)
+symbol::symbol(const std::string & initname, unsigned domain)
+ : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(default_TeX_name()), ret_type(return_types::commutative), ret_type_tinfo(TINFO_symbol), domain(domain)
 {
        setflag(status_flags::evaluated | status_flags::expanded);
 }
 
-symbol::symbol(const std::string & initname, const std::string & texname)
- : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(texname), ret_type(return_types::commutative), ret_type_tinfo(TINFO_symbol)
+symbol::symbol(const std::string & initname, const std::string & texname, unsigned domain)
+ : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(texname), ret_type(return_types::commutative), ret_type_tinfo(TINFO_symbol), domain(domain)
 {
        setflag(status_flags::evaluated | status_flags::expanded);
 }
 
-symbol::symbol(const std::string & initname, unsigned rt, unsigned rtt)
- : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(default_TeX_name()), ret_type(rt), ret_type_tinfo(rtt)
+symbol::symbol(const std::string & initname, unsigned rt, unsigned rtt, unsigned domain)
+ : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(default_TeX_name()), ret_type(rt), ret_type_tinfo(rtt), domain(domain)
 {
        setflag(status_flags::evaluated | status_flags::expanded);
 }
 
-symbol::symbol(const std::string & initname, const std::string & texname, unsigned rt, unsigned rtt)
- : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(texname), ret_type(rt), ret_type_tinfo(rtt)
+symbol::symbol(const std::string & initname, const std::string & texname, unsigned rt, unsigned rtt, unsigned domain)
+ : inherited(TINFO_symbol), asexinfop(new assigned_ex_info), serial(next_serial++), name(initname), TeX_name(texname), ret_type(rt), ret_type_tinfo(rtt), domain(domain)
 {
        setflag(status_flags::evaluated | status_flags::expanded);
 }
@@ -83,12 +84,14 @@ symbol::symbol(const std::string & initname, const std::string & texname, unsign
 
 /** Construct object from archive_node. */
 symbol::symbol(const archive_node &n, lst &sym_lst)
- : inherited(n, sym_lst), asexinfop(new assigned_ex_info), serial(next_serial++), ret_type(return_types::commutative), ret_type_tinfo(TINFO_symbol)
+ : inherited(n, sym_lst), asexinfop(new assigned_ex_info), serial(next_serial++)
 {
-       if (!(n.find_string("name", name)))
+       if (!n.find_string("name", name))
                name = autoname_prefix() + ToString(serial);
-       if (!(n.find_string("TeXname", TeX_name)))
+       if (!n.find_string("TeXname", TeX_name))
                TeX_name = default_TeX_name();
+       if (!n.find_unsigned("domain", domain))
+               domain = symbol_options::complex;
        if (!n.find_unsigned("return_type", ret_type))
                ret_type = return_types::commutative;
        if (!n.find_unsigned("return_type_tinfo", ret_type_tinfo))
@@ -119,6 +122,8 @@ void symbol::archive(archive_node &n) const
        n.add_string("name", name);
        if (TeX_name != default_TeX_name())
                n.add_string("TeX_name", TeX_name);
+       if (domain != symbol_options::complex)
+               n.add_unsigned("domain", domain);
        if (ret_type != return_types::commutative)
                n.add_unsigned("return_type", ret_type);
        if (ret_type_tinfo != TINFO_symbol)
@@ -146,6 +151,7 @@ void symbol::do_print_tree(const print_tree & c, unsigned level) const
        c.s << std::string(level, ' ') << name << " (" << class_name() << ")" << " @" << this
            << ", serial=" << serial
            << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+           << ", domain=" << domain
            << std::endl;
 }
 
@@ -187,6 +193,15 @@ ex symbol::eval(int level) const
        }
 }
 
+ex symbol::conjugate() const
+{
+       if (this->domain == symbol_options::complex) {
+               return GiNaC::conjugate(*this).hold();
+       } else {
+               return *this;
+       }
+}
+
 // protected
 
 /** Implementation of ex::diff() for single differentiation of a symbol.
index 0b6844a..a8e667f 100644 (file)
@@ -3,7 +3,7 @@
  *  Interface to GiNaC's symbolic objects. */
 
 /*
- *  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
@@ -54,10 +54,10 @@ class symbol : public basic
        
        // other constructors
 public:
-       explicit symbol(const std::string & initname);
-       symbol(const std::string & initname, const std::string & texname);
-       symbol(const std::string & initname, unsigned rt, unsigned rtt);
-       symbol(const std::string & initname, const std::string & texname, unsigned rt, unsigned rtt);
+       explicit symbol(const std::string & initname, unsigned domain = symbol_options::complex);
+       symbol(const std::string & initname, const std::string & texname, unsigned domain = symbol_options::complex);
+       symbol(const std::string & initname, unsigned rt, unsigned rtt, unsigned domain = symbol_options::complex);
+       symbol(const std::string & initname, const std::string & texname, unsigned rt, unsigned rtt, unsigned domain = symbol_options::complex);
        
        // functions overriding virtual functions from base classes
 public:
@@ -71,6 +71,7 @@ public:
        ex to_polynomial(exmap & repl) const;
        unsigned return_type() const { return ret_type; }
        unsigned return_type_tinfo() const { return ret_type_tinfo; }
+       ex conjugate() const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
@@ -82,6 +83,7 @@ public:
        void unassign();
        void set_name(const std::string & n) { name = n; }
        std::string get_name() const { return name; }
+       unsigned get_domain() const { return domain; }
 protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
@@ -98,6 +100,7 @@ protected:
        unsigned serial;                 ///< unique serial number for comparison
        std::string name;                ///< printname of this symbol
        std::string TeX_name;            ///< LaTeX name of this symbol
+       unsigned domain;                 ///< domain of symbol, complex (default) or real
        unsigned ret_type;               ///< value returned by return_type()
        unsigned ret_type_tinfo;         ///< value returned by return_type_tinfo()
 private: