]> www.ginac.de Git - ginac.git/blobdiff - ginac/ncmul.cpp
- fix LaTeX-output bug reported by Stefan, remove obsolete has(matrix,ex).
[ginac.git] / ginac / ncmul.cpp
index 1aa436339294ffcbe3214062800e2d2e73e90d5f..8a0cc1220311d5eb7c0070fb76dd552e1ba28813 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's non-commutative products of expressions. */
 
 /*
- *  GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2001 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
 #include "ex.h"
 #include "add.h"
 #include "mul.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(ncmul, exprseq)
 
@@ -42,47 +41,14 @@ GINAC_IMPLEMENT_REGISTERED_CLASS(ncmul, exprseq)
 // default constructor, destructor, copy constructor assignment operator and helpers
 //////////
 
-// public
-
 ncmul::ncmul()
 {
        debugmsg("ncmul default constructor",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_ncmul;
 }
 
-ncmul::~ncmul()
-{
-       debugmsg("ncmul destructor",LOGLEVEL_DESTRUCT);
-       destroy(0);
-}
-
-ncmul::ncmul(const ncmul & other)
-{
-       debugmsg("ncmul copy constructor",LOGLEVEL_CONSTRUCT);
-       copy(other);
-}
-
-const ncmul & ncmul::operator=(const ncmul & other)
-{
-       debugmsg("ncmul operator=",LOGLEVEL_ASSIGNMENT);
-       if (this != &other) {
-               destroy(1);
-               copy(other);
-       }
-       return *this;
-}
-
-// protected
-
-void ncmul::copy(const ncmul & other)
-{
-       inherited::copy(other);
-}
-
-void ncmul::destroy(bool call_parent)
-{
-       if (call_parent) inherited::destroy(call_parent);
-}
+DEFAULT_COPY(ncmul)
+DEFAULT_DESTROY(ncmul)
 
 //////////
 // other constructors
@@ -90,37 +56,34 @@ void ncmul::destroy(bool call_parent)
 
 // public
 
-ncmul::ncmul(const ex & lh, const ex & rh) :
-       inherited(lh,rh)
+ncmul::ncmul(const ex & lh, const ex & rh) : inherited(lh,rh)
 {
        debugmsg("ncmul constructor from ex,ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_ncmul;
 }
 
-ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3) :
-       inherited(f1,f2,f3)
+ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3) : inherited(f1,f2,f3)
 {
        debugmsg("ncmul constructor from 3 ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_ncmul;
 }
 
 ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3,
-         const ex & f4) : inherited(f1,f2,f3,f4)
+             const ex & f4) : inherited(f1,f2,f3,f4)
 {
        debugmsg("ncmul constructor from 4 ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_ncmul;
 }
 
 ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3,
-         const ex & f4, const ex & f5) : inherited(f1,f2,f3,f4,f5)
+             const ex & f4, const ex & f5) : inherited(f1,f2,f3,f4,f5)
 {
        debugmsg("ncmul constructor from 5 ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_ncmul;
 }
 
 ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3,
-         const ex & f4, const ex & f5, const ex & f6) :
-       inherited(f1,f2,f3,f4,f5,f6)
+             const ex & f4, const ex & f5, const ex & f6) : inherited(f1,f2,f3,f4,f5,f6)
 {
        debugmsg("ncmul constructor from 6 ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_ncmul;
@@ -142,24 +105,7 @@ ncmul::ncmul(exvector * vp) : inherited(vp)
 // archiving
 //////////
 
-/** Construct object from archive_node. */
-ncmul::ncmul(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
-{
-       debugmsg("ncmul constructor from archive_node", LOGLEVEL_CONSTRUCT);
-}
-
-/** Unarchive the object. */
-ex ncmul::unarchive(const archive_node &n, const lst &sym_lst)
-{
-       return (new ncmul(n, sym_lst))->setflag(status_flags::dynallocated);
-}
-
-/** Archive the object. */
-void ncmul::archive(archive_node &n) const
-{
-       inherited::archive(n);
-}
-
+DEFAULT_ARCHIVING(ncmul)
        
 //////////
 // functions overriding virtual functions from bases classes
@@ -167,43 +113,28 @@ void ncmul::archive(archive_node &n) const
 
 // public
 
-basic * ncmul::duplicate() const
+void ncmul::print(const print_context & c, unsigned level) const
 {
-       debugmsg("ncmul duplicate",LOGLEVEL_ASSIGNMENT);
-       return new ncmul(*this);
-}
+       debugmsg("ncmul print", LOGLEVEL_PRINT);
 
-void ncmul::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("ncmul print",LOGLEVEL_PRINT);
-       printseq(os,'(','%',')',precedence,upper_precedence);
-}
+       if (is_of_type(c, print_tree)) {
 
-void ncmul::printraw(std::ostream & os) const
-{
-       debugmsg("ncmul printraw",LOGLEVEL_PRINT);
+               inherited::print(c, level);
 
-       os << "%(";
-       for (exvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
-               (*it).bp->printraw(os);
-               os << ",";
-       }
-       os << ",hash=" << hashvalue << ",flags=" << flags;
-       os << ")";
-}
+       } else if (is_of_type(c, print_csrc)) {
 
-void ncmul::printcsrc(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("ncmul print csrc",LOGLEVEL_PRINT);
-       exvector::const_iterator it;
-       exvector::const_iterator itend = seq.end()-1;
-       os << "ncmul(";
-       for (it=seq.begin(); it!=itend; ++it) {
-               (*it).bp->printcsrc(os,precedence);
-               os << ",";
-       }
-       (*it).bp->printcsrc(os,precedence);
-       os << ")";
+               c.s << "ncmul(";
+               exvector::const_iterator it = seq.begin(), itend = seq.end()-1;
+               while (it != itend) {
+                       it->print(c, precedence());
+                       c.s << ",";
+                       it++;
+               }
+               it->print(c, precedence());
+               c.s << ")";
+
+       } else
+               printseq(c, '(', '*', ')', precedence(), level);
 }
 
 bool ncmul::info(unsigned inf) const
@@ -280,7 +211,7 @@ ex ncmul::expand(unsigned options) const
                                                                                status_flags::expanded);
 }
 
-int ncmul::degree(const symbol & s) const
+int ncmul::degree(const ex & s) const
 {
        int deg_sum=0;
        for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
@@ -289,7 +220,7 @@ int ncmul::degree(const symbol & s) const
        return deg_sum;
 }
 
-int ncmul::ldegree(const symbol & s) const
+int ncmul::ldegree(const ex & s) const
 {
        int deg_sum=0;
        for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
@@ -298,7 +229,7 @@ int ncmul::ldegree(const symbol & s) const
        return deg_sum;
 }
 
-ex ncmul::coeff(const symbol & s, int n) const
+ex ncmul::coeff(const ex & s, int n) const
 {
        exvector coeffseq;
        coeffseq.reserve(seq.size());
@@ -366,11 +297,11 @@ ex ncmul::eval(int level) const
        //                      ncmul(...,x1,x2,...,x3,x4,...) (associativity)
        //                  ncmul(x) -> x
        //                  ncmul() -> 1
-       //                  ncmul(...,c1,...,c2,...) ->
+       //                  ncmul(...,c1,...,c2,...)
        //                      *(c1,c2,ncmul(...)) (pull out commutative elements)
        //                  ncmul(x1,y1,x2,y2) -> *(ncmul(x1,x2),ncmul(y1,y2))
        //                      (collect elements of same type)
-       //                  ncmul(x1,x2,x3,...) -> x::eval_ncmul(x1,x2,x3,...)
+       //                  ncmul(x1,x2,x3,...) -> x::simplify_ncmul(x1,x2,x3,...)
        // the following rule would be nice, but produces a recursion,
        // which must be trapped by introducing a flag that the sub-ncmuls()
        // are already evaluated (maybe later...)
@@ -378,7 +309,7 @@ ex ncmul::eval(int level) const
        //                      ncmul(ncmul(x1,x2,...),X,ncmul(y1,y2,...)
        //                      (X noncommutative_composite)
 
-       if ((level==1)&&(flags & status_flags::evaluated)) {
+       if ((level==1) && (flags & status_flags::evaluated)) {
                return *this;
        }
 
@@ -387,16 +318,14 @@ ex ncmul::eval(int level) const
        // ncmul(...,*(x1,x2),...,ncmul(x3,x4),...) ->
        //     ncmul(...,x1,x2,...,x3,x4,...) (associativity)
        unsigned factors=0;
-       for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit) {
+       for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit)
                factors += count_factors(*cit);
-       }
-
+       
        exvector assocseq;
        assocseq.reserve(factors);
-       for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit) {
+       for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit)
                append_factors(assocseq,*cit);
-       }
-
+       
        // ncmul(x) -> x
        if (assocseq.size()==1) return *(seq.begin());
 
@@ -436,14 +365,12 @@ ex ncmul::eval(int level) const
                exvector noncommutativeseq;
                noncommutativeseq.reserve(assocseq.size()-count_commutative);
                for (i=0; i<assocseq.size(); ++i) {
-                       if (rettypes[i]==return_types::commutative) {
+                       if (rettypes[i]==return_types::commutative)
                                commutativeseq.push_back(assocseq[i]);
-                       } else {
+                       else
                                noncommutativeseq.push_back(assocseq[i]);
-                       }
                }
-               commutativeseq.push_back((new ncmul(noncommutativeseq,1))->
-                                                                 setflag(status_flags::dynallocated));
+               commutativeseq.push_back((new ncmul(noncommutativeseq,1))->setflag(status_flags::dynallocated));
                return (new mul(commutativeseq))->setflag(status_flags::dynallocated);
        }
                
@@ -489,17 +416,15 @@ ex ncmul::eval(int level) const
 #endif // def DO_GINAC_ASSERT
                
                // if all elements are of same type, simplify the string
-               if (evv.size()==1) {
+               if (evv.size()==1)
                        return evv[0][0].simplify_ncmul(evv[0]);
-               }
                
                exvector splitseq;
                splitseq.reserve(evv.size());
                for (i=0; i<evv.size(); ++i) {
-                       splitseq.push_back((new ncmul(evv[i]))->
-                                                          setflag(status_flags::dynallocated));
+                       splitseq.push_back((new ncmul(evv[i]))->setflag(status_flags::dynallocated));
                }
-
+               
                return (new mul(splitseq))->setflag(status_flags::dynallocated);
        }
        
@@ -507,25 +432,6 @@ ex ncmul::eval(int level) const
                                                                                  status_flags::evaluated);
 }
 
-exvector ncmul::get_indices(void) const
-{
-       // return union of indices of factors
-       exvector iv;
-       for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               exvector subiv=(*cit).get_indices();
-               iv.reserve(iv.size()+subiv.size());
-               for (exvector::const_iterator cit2=subiv.begin(); cit2!=subiv.end(); ++cit2) {
-                       iv.push_back(*cit2);
-               }
-       }
-       return iv;
-}
-
-ex ncmul::subs(const lst & ls, const lst & lr) const
-{
-       return ncmul(subschildren(ls, lr));
-}
-
 ex ncmul::thisexprseq(const exvector & v) const
 {
        return (new ncmul(v))->setflag(status_flags::dynallocated);
@@ -570,10 +476,10 @@ unsigned ncmul::return_type(void) const
                        all_commutative=0;
                }
                if ((rt==return_types::noncommutative)&&(!all_commutative)) {
-               // another nc element found, compare type_infos
+                       // another nc element found, compare type_infos
                        if ((*cit_noncommutative_element).return_type_tinfo()!=(*cit).return_type_tinfo()) {
-                       // diffent types -> mul is ncc
-                       return return_types::noncommutative_composite;
+                               // diffent types -> mul is ncc
+                               return return_types::noncommutative_composite;
                        }
                }
        }
@@ -624,22 +530,6 @@ const exvector & ncmul::get_factors(void) const
        return seq;
 }
 
-//////////
-// static member variables
-//////////
-
-// protected
-
-unsigned ncmul::precedence=50;
-
-
-//////////
-// global constants
-//////////
-
-const ncmul some_ncmul;
-const type_info & typeid_ncmul=typeid(some_ncmul);
-
 //////////
 // friend functions
 //////////
@@ -657,9 +547,7 @@ ex simplified_ncmul(const exvector & v)
                return v[0];
        }
        return (new ncmul(v))->setflag(status_flags::dynallocated |
-                                                                  status_flags::evaluated);
+                                      status_flags::evaluated);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC