Ticket #9880: trac9880_pynac_order_burcin_original.patch

File trac9880_pynac_order_burcin_original.patch, 28.6 KB (added by jpflori, 11 years ago)

Burcin original patch

  • ginac/Makefile.am

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1284298206 -7200
    # Node ID a8d8d201814186823ebc1204f5acf55e0b8b5b91
    # Parent  b233d9dadcfa72b9159000f1055fef61abe0cae7
    Revert the changes to the original comparison functions of GiNaC and use the
    new comparison functions only in the printing of add and mul objects.
    
    diff --git a/ginac/Makefile.am b/ginac/Makefile.am
    a b  
    1010  operators.cpp power.cpp registrar.cpp relational.cpp remember.cpp \
    1111  pseries.cpp print.cpp symbol.cpp symmetry.cpp tensor.cpp \
    1212  utils.cpp wildcard.cpp \
    13   remember.h tostring.h utils.h compiler.h
     13  remember.h tostring.h utils.h compiler.h order.cpp
    1414
    1515#The -no-undefined breaks Pynac on OS X 10.4.  See #9135
    1616if CYGWIN
     
    2626  exprseq.h fail.h fderivative.h flags.h function.h hash_map.h idx.h indexed.h \
    2727  inifcns.h integral.h lst.h matrix.h mul.h ncmul.h normal.h numeric.h operators.h \
    2828  power.h print.h pseries.h ptr.h registrar.h relational.h structure.h \
    29   symbol.h symmetry.h tensor.h version.h wildcard.h
     29  symbol.h symmetry.h tensor.h version.h wildcard.h order.h
    3030EXTRA_DIST = version.h.in
  • ginac/add.cpp

    diff --git a/ginac/add.cpp b/ginac/add.cpp
    a b  
    125125        numeric coeff;
    126126        bool first = true;
    127127
     128        epvector* sorted_seq = get_sorted_seq();
    128129        // Then proceed with the remaining factors
    129         epvector::const_iterator it = seq.begin(), itend = seq.end();
     130        epvector::const_iterator it = sorted_seq->begin(), itend = sorted_seq->end();
    130131        while (it != itend) {
    131132                std::stringstream tstream;
    132133                print_context *tcontext_p;
  • ginac/basic.cpp

    diff --git a/ginac/basic.cpp b/ginac/basic.cpp
    a b  
    829829 *  1 greater. */
    830830int basic::compare(const basic & other) const
    831831{
     832 #ifdef GINAC_COMPARE_STATISTICS
     833        compare_statistics.total_basic_compares++;
     834#endif
     835        const unsigned hash_this = gethash();
     836        const unsigned hash_other = other.gethash();
     837        if (hash_this<hash_other) return -1;
     838        if (hash_this>hash_other) return 1;
    832839#ifdef GINAC_COMPARE_STATISTICS
    833         compare_statistics.total_basic_compares++;
    834 #endif
    835         static const tinfo_t function_id = find_tinfo_key("function");
    836         static const tinfo_t fderivative_id = find_tinfo_key("fderivative");
    837         const tinfo_t typeid_this = tinfo();
    838         const tinfo_t typeid_other = other.tinfo();
    839 
    840         // SAGE: If we want orderings to make any sense, it only
    841         // makes sense to compare using the hashes when the types
    842         // are the same.  WARNING -- doing this *will* presumably
    843         // have negative performance implications.
    844         /*      if (typeid_this==typeid_other) {
    845           const unsigned hash_this = gethash();
    846           const unsigned hash_other = other.gethash();
    847           if (hash_this<hash_other) return -1;
    848           if (hash_this>hash_other) return 1;
    849         }
    850         */
    851 
    852 #ifdef GINAC_COMPARE_STATISTICS
    853         compare_statistics.compare_same_hashvalue++;
     840        compare_statistics.compare_same_hashvalue++;
    854841#endif
    855842
    856         if (typeid_this==typeid_other) {
    857                 GINAC_ASSERT(typeid(*this)==typeid(other));
    858 //              int cmpval = compare_same_type(other);
    859 //              if (cmpval!=0) {
    860 //                      std::cout << "hash collision, same type: "
    861 //                                << *this << " and " << other << std::endl;
    862 //                      this->print(print_tree(std::cout));
    863 //                      std::cout << " and ";
    864 //                      other.print(print_tree(std::cout));
    865 //                      std::cout << std::endl;
    866 //              }
    867 //              return cmpval;
     843        const tinfo_t& typeid_this = tinfo();//typeid(*this);
     844        const tinfo_t& typeid_other = other.tinfo();//typeid(other);
     845        if (typeid_this == typeid_other) {
     846//              int cmpval = compare_same_type(other);
     847//              if (cmpval!=0) {
     848//                      std::cout << "hash collision, same type: "
     849//                                << *this << " and " << other << std::endl;
     850//                      this->print(print_tree(std::cout));
     851//                      std::cout << " and ";
     852//                      other.print(print_tree(std::cout));
     853//                      std::cout << std::endl;
     854//              }
     855//              return cmpval;
    868856#ifdef GINAC_COMPARE_STATISTICS
    869                 compare_statistics.compare_same_type++;
     857                compare_statistics.compare_same_type++;
    870858#endif
    871                 return compare_same_type(other);
    872         } else if (typeid_other == function_id ||
    873                         typeid_other == fderivative_id) {
    874                 return -1;
    875         } else {
    876 //              std::cout << "hash collision, different types: "
    877 //                        << *this << " and " << other << std::endl;
    878 //              this->print(print_tree(std::cout));
    879 //              std::cout << " and ";
    880 //              other.print(print_tree(std::cout));
    881 //              std::cout << std::endl;
     859                return compare_same_type(other);
     860        } else {
     861//              std::cout << "hash collision, different types: "
     862//                        << *this << " and " << other << std::endl;
     863//              this->print(print_tree(std::cout));
     864//              std::cout << " and ";
     865//              other.print(print_tree(std::cout));
     866//              std::cout << std::endl;
     867                //return (typeid_this.before(typeid_other) ? -1 : 1);
    882868                return (typeid_this<typeid_other ? -1 : 1);
    883         }
     869        }
    884870}
    885871
    886872/** Test for syntactic equality.
  • ginac/basic.h

    diff --git a/ginac/basic.h b/ginac/basic.h
    a b  
    108108        GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(basic, void)
    109109       
    110110        friend class ex;
     111        friend struct ex_is_greater_degrevlex;
    111112       
    112113        // default constructor, destructor, copy constructor and assignment operator
    113114protected:
  • ginac/ex.cpp

    diff --git a/ginac/ex.cpp b/ginac/ex.cpp
    a b  
    584584
    585585// none
    586586
    587 
     587//
    588588} // namespace GiNaC
  • ginac/ex.h

    diff --git a/ginac/ex.h b/ginac/ex.h
    a b  
    7878        template<class T> friend inline bool is_a(const ex &);
    7979        template<class T> friend inline bool is_exactly_a(const ex &);
    8080       
     81        friend struct ex_is_greater_degrevlex;
    8182        // default constructor, copy constructor and assignment operator
    8283public:
    8384        ex() throw();
     
    695696        void operator() (ex &lh, ex &rh) const { lh.swap(rh); }
    696697};
    697698
     699
    698700// Make it possible to print exvectors and exmaps
    699701std::ostream & operator<<(std::ostream & os, const exvector & e);
    700702std::ostream & operator<<(std::ostream & os, const exset & e);
  • ginac/expairseq.cpp

    diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp
    a b  
    3232#include "utils.h"
    3333#include "indexed.h"
    3434#include "constant.h"
     35#include "order.h"
    3536
    3637#include <iostream>
    3738#include <algorithm>
     
    7071
    7172// public
    7273
    73 expairseq::expairseq() : inherited(&expairseq::tinfo_static)
     74expairseq::expairseq() : inherited(&expairseq::tinfo_static), seq_sorted(NULL)
    7475#if EXPAIRSEQ_USE_HASHTAB
    7576                                                   , hashtabsize(0)
    7677#endif // EXPAIRSEQ_USE_HASHTAB
     
    109110// other constructors
    110111//////////
    111112
    112 expairseq::expairseq(const ex &lh, const ex &rh) : inherited(&expairseq::tinfo_static)
     113expairseq::expairseq(const ex &lh, const ex &rh) : inherited(&expairseq::tinfo_static), seq_sorted(NULL)
    113114{
    114115        construct_from_2_ex(lh,rh);
    115116        GINAC_ASSERT(is_canonical());
    116117}
    117118
    118 expairseq::expairseq(const exvector &v) : inherited(&expairseq::tinfo_static)
     119expairseq::expairseq(const exvector &v) : inherited(&expairseq::tinfo_static), seq_sorted(NULL)
    119120{
    120121        construct_from_exvector(v);
    121122        GINAC_ASSERT(is_canonical());
    122123}
    123124
    124125expairseq::expairseq(const epvector &v, const ex &oc, bool do_index_renaming)
    125   : inherited(&expairseq::tinfo_static), overall_coeff(oc)
     126  : inherited(&expairseq::tinfo_static), overall_coeff(oc), seq_sorted(NULL)
    126127{
    127128        GINAC_ASSERT(is_a<numeric>(oc));
    128129        construct_from_epvector(v, do_index_renaming);
     
    130131}
    131132
    132133expairseq::expairseq(std::auto_ptr<epvector> vp, const ex &oc, bool do_index_renaming)
    133   : inherited(&expairseq::tinfo_static), overall_coeff(oc)
     134  : inherited(&expairseq::tinfo_static), overall_coeff(oc), seq_sorted(NULL)
    134135{
    135136        GINAC_ASSERT(vp.get()!=0);
    136137        GINAC_ASSERT(is_a<numeric>(oc));
     
    142143// archiving
    143144//////////
    144145
    145 expairseq::expairseq(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
     146expairseq::expairseq(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst), seq_sorted(NULL)
    146147#if EXPAIRSEQ_USE_HASHTAB
    147148        , hashtabsize(0)
    148149#endif
     
    504505{
    505506        GINAC_ASSERT(is_a<expairseq>(other));
    506507        const expairseq &o = static_cast<const expairseq &>(other);
    507        
     508
    508509        int cmpval;
    509        
     510
    510511        // compare number of elements
    511512        if (seq.size() != o.seq.size())
    512513                return (seq.size()<o.seq.size()) ? -1 : 1;
    513514
     515        // compare overall_coeff
     516        cmpval = overall_coeff.compare(o.overall_coeff);
     517        if (cmpval!=0)
     518                return cmpval;
     519
    514520#if EXPAIRSEQ_USE_HASHTAB
    515521        GINAC_ASSERT(hashtabsize==o.hashtabsize);
    516522        if (hashtabsize==0) {
    517523#endif // EXPAIRSEQ_USE_HASHTAB
     524
    518525                epvector::const_iterator cit1 = seq.begin();
    519526                epvector::const_iterator cit2 = o.seq.begin();
    520527                epvector::const_iterator last1 = seq.end();
    521528                epvector::const_iterator last2 = o.seq.end();
    522529
    523530                for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
    524                         cmpval = (*cit2).compare(*cit1);
     531                        cmpval = (*cit1).compare(*cit2);
    525532                        if (cmpval!=0) return cmpval;
    526533                }
    527534
    528535                GINAC_ASSERT(cit1==last1);
    529536                GINAC_ASSERT(cit2==last2);
    530        
    531                 // compare overall_coeff
    532                 cmpval = overall_coeff.compare(o.overall_coeff);
    533                 if (cmpval!=0)
    534                         return cmpval;
    535        
     537
    536538                return 0;
     539
    537540#if EXPAIRSEQ_USE_HASHTAB
    538541        }
    539        
     542
    540543        // compare number of elements in each hashtab entry
    541544        for (unsigned i=0; i<hashtabsize; ++i) {
    542545                unsigned cursize=hashtab[i].size();
    543546                if (cursize != o.hashtab[i].size())
    544547                        return (cursize < o.hashtab[i].size()) ? -1 : 1;
    545548        }
    546        
     549
    547550        // compare individual (sorted) hashtab entries
    548551        for (unsigned i=0; i<hashtabsize; ++i) {
    549552                unsigned sz = hashtab[i].size();
     
    561564                        }
    562565                }
    563566        }
    564        
    565567        return 0; // equal
    566568#endif // EXPAIRSEQ_USE_HASHTAB
    567569}
     
    11821184        std::sort(seq.begin(), seq.end(), expair_rest_is_less());
    11831185}
    11841186
     1187epvector* expairseq::get_sorted_seq() const
     1188{
     1189        if (!this->seq_sorted) {
     1190                seq_sorted = new epvector(seq.size());
     1191                partial_sort_copy(seq.begin(), seq.end(),
     1192                                seq_sorted->begin(), seq_sorted->end(),
     1193                                expair_rest_is_greater_degrevlex());
     1194        }
     1195        return seq_sorted;
     1196}
     1197
    11851198
    11861199/** Compact a presorted expairseq by combining all matching expairs to one
    11871200 *  each.  On an add object, this is responsible for 2*x+3*x+y -> 5*x+y, for
  • ginac/expairseq.h

    diff --git a/ginac/expairseq.h b/ginac/expairseq.h
    a b  
    6767{
    6868        GINAC_DECLARE_REGISTERED_CLASS(expairseq, basic)
    6969
     70        friend struct ex_is_greater_degrevlex;
    7071        // other constructors
    7172public:
    7273        expairseq(const ex & lh, const ex & rh);
     
    158159        std::auto_ptr<epvector> evalchildren(int level) const;
    159160        std::auto_ptr<epvector> subschildren(const exmap & m, unsigned options = 0) const;
    160161       
     162        epvector* get_sorted_seq() const;
    161163// member variables
    162164       
    163165protected:
    164166        epvector seq;
     167        mutable epvector *seq_sorted;
    165168        ex overall_coeff;
    166169#if EXPAIRSEQ_USE_HASHTAB
    167170        epplistvector hashtab;
  • ginac/function.cpp

    diff --git a/ginac/function.cpp b/ginac/function.cpp
    a b  
    11821182        return result;
    11831183}
    11841184
     1185/*
    11851186int function::compare(const basic& other) const
    11861187{
    11871188        static const tinfo_t function_id = find_tinfo_key("function");
     
    11991200                return 1;
    12001201        }
    12011202}
     1203*/
    12021204
    12031205int function::compare_same_type(const basic & other) const
    12041206{
     
    12111213                return exprseq::compare_same_type(o);
    12121214}
    12131215
     1216
    12141217bool function::is_equal_same_type(const basic & other) const
    12151218{
    12161219        GINAC_ASSERT(is_a<function>(other));
  • ginac/function.h

    diff --git a/ginac/function.h b/ginac/function.h
    a b  
    347347        ex conjugate() const;
    348348        ex real_part() const;
    349349        ex imag_part() const;
    350         int compare(const basic &other) const;
     350        //int compare(const basic &other) const;
    351351protected:
    352352        ex derivative(const symbol & s) const;
    353353        bool is_equal_same_type(const basic & other) const;
  • ginac/mul.cpp

    diff --git a/ginac/mul.cpp b/ginac/mul.cpp
    a b  
    3636
    3737#include <iostream>
    3838#include <vector>
     39#include <cmath>
    3940#include <stdexcept>
    4041#include <limits>
    41 #include <cmath>
    4242#include <sstream>
    4343
    4444namespace GiNaC {
     
    257257
    258258        // Separate factors into those with negative numeric exponent
    259259        // and all others
    260         epvector::const_iterator it = seq.begin(), itend = seq.end();
     260        epvector* sorted_seq = get_sorted_seq();
     261        epvector::const_iterator it = sorted_seq->begin(), itend = sorted_seq->end();
     262        //epvector::const_iterator it = seq.begin(), itend = seq.end();
    261263        exvector neg_powers, others;
    262264        while (it != itend) {
    263265                GINAC_ASSERT(is_exactly_a<numeric>(it->coeff));
     
    12001202        return tdegree;
    12011203}
    12021204
     1205/*
    12031206int mul::compare(const basic& other) const
    12041207{
    12051208        static const tinfo_t function_id = find_tinfo_key("function");
     
    12221225                return (typeid_this<typeid_other ? -1 : 1);
    12231226        }
    12241227}
    1225 
    1226 int mul::compare_symbol(const symbol &other) const
    1227 {
    1228         int cmpval;
    1229         double tdeg;
    1230         tdeg = total_degree();
    1231         if (tdeg == 1) {
    1232                 cmpval = seq[0].rest.compare(other);
    1233                 if (cmpval != 0) {
    1234                         return cmpval;
    1235                 }
    1236                 cmpval = _ex1.compare(seq[0].coeff);
    1237                 if (cmpval != 0) {
    1238                         return cmpval;
    1239                 }
    1240                 return -1;
    1241         }
    1242         return tdeg > 1 ? -1 : 1;
    1243 }
    1244 
    1245 // compare this to a pow object
    1246 // first we compare degrees
    1247 // if equal we compare the first item in the sequence to the base in other
    1248 int mul::compare_pow(const power &other) const
    1249 {
    1250         double my_deg = total_degree();
    1251         double odeg;
    1252         numeric oexp;
    1253         int cmpval = 0;
    1254         if (is_a<numeric>(other.exponent)) {
    1255                 numeric oexp = ex_to<numeric>(other.exponent);
    1256                 if (oexp.is_real()) {
    1257                         odeg = oexp.to_double();
    1258                 } else {
    1259                         odeg = std::sqrt(std::pow(oexp.real().to_double(), 2) +
    1260                                         std::pow(oexp.imag().to_double(), 2));
    1261                 }
    1262                 if (odeg != my_deg)
    1263                         return my_deg < odeg ? 1 : -1;
    1264         } else {
    1265                 cmpval = seq[0].coeff.compare(other.exponent);
    1266                 if (cmpval != 0)
    1267                         return cmpval;
    1268         }
    1269         cmpval = seq[0].rest.compare(other.basis);
    1270         if (cmpval != 0) {
    1271                 return cmpval;
    1272         }
    1273         if (seq.size() == 1 && overall_coeff.is_equal(_ex1))
    1274                 return 0;
    1275         return 1;
    1276 }
     1228*/
    12771229
    12781230
    12791231int mul::compare_same_type(const basic & other) const
    12801232{
    1281         int cmpval;
    1282 
    1283         const mul &o = static_cast<const mul &>(other);
    1284 
    1285         // compare total degrees
    1286         double deg1 = total_degree();
    1287         double deg2 = o.total_degree();
    1288         if (deg1 != deg2)
    1289                 return deg1 < deg2 ? 1 : -1;
    1290 
    1291         // compare each item in this product to correnponding element in other
    1292         epvector::const_iterator cit1 = seq.begin();
    1293         epvector::const_iterator cit2 = o.seq.begin();
    1294         epvector::const_iterator last1 = seq.end();
    1295         epvector::const_iterator last2 = o.seq.end();
    1296 
    1297         for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
    1298                 cmpval = (*cit1).compare(*cit2);
    1299                 if (cmpval != 0)
    1300                         return cmpval;
    1301         }
    1302 
    1303         // compare sizes
    1304         if (cit1 != last1)
    1305                 return 1;
    1306         else if (cit2 != last2)
    1307                 return -1;
    1308 
    1309         // compare overall_coeff
    1310         cmpval = overall_coeff.compare(o.overall_coeff);
    1311         if (cmpval!=0)
    1312                 return cmpval;
    1313 
    1314         return 0;
     1233        return inherited::compare_same_type(other);
    13151234}
    13161235
    13171236unsigned mul::return_type() const
  • ginac/mul.h

    diff --git a/ginac/mul.h b/ginac/mul.h
    a b  
    8383        bool can_make_flat(const expair & p) const;
    8484        ex expand(unsigned options=0) const;
    8585        void find_real_imag(ex&, ex&) const;
    86         int compare(const basic& other) const;
     86        //int compare(const basic& other) const;
    8787       
    8888        // new virtual functions which can be overridden by derived classes
    8989        // none
     
    9292public:
    9393        ex algebraic_subs_mul(const exmap & m, unsigned options) const;
    9494        double total_degree() const;
    95         int compare_symbol(const symbol &other) const;
    96         int compare_pow(const power &other) const;
     95        //int compare_symbol(const symbol &other) const;
     96        //int compare_pow(const power &other) const;
    9797protected:
    9898        void print_overall_coeff(const ex coeff_ex, const print_context & c,
    9999                        const char *mul_sym, bool latex=false) const;
  • new file ginac/order.cpp

    diff --git a/ginac/order.cpp b/ginac/order.cpp
    new file mode 100644
    - +  
     1
     2#include "order.h"
     3#include "registrar.h"
     4#include "utils.h"
     5
     6#include <cmath>
     7#include <iostream>
     8
     9namespace GiNaC {
     10
     11
     12bool ex_is_greater_degrevlex::operator() (const ex &lhex, const ex &rhex) const {
     13        //std::cout<<"in ex_is_greater_degrevlex::operator()"<<std::endl;
     14        //std::cout<<"lh: ";
     15        //lhex.dbgprint();
     16        //std::cout<<std::endl<<"rh: ";
     17        //rhex.dbgprint();
     18        //std::cout<<std::endl;
     19        const basic *lh = get_pointer(lhex.bp);
     20        const basic *rh = get_pointer(rhex.bp);
     21        return compare(lh, rh) == 1;
     22}
     23
     24int ex_is_greater_degrevlex::compare(const basic *lh, const basic *rh) const {
     25        const tinfo_t typeid_lh = lh->tinfo();
     26        const tinfo_t typeid_rh = rh->tinfo();
     27
     28        if (typeid_rh==typeid_lh) {
     29                if (typeid_rh == mul_id) {
     30                        return compare_same_type_mul(
     31                                        static_cast<const mul*>(lh),
     32                                        static_cast<const mul*>(rh));
     33                } else if (typeid_rh == add_id) {
     34                        return compare_same_type_add(
     35                                        static_cast<const add*>(lh),
     36                                        static_cast<const add*>(rh));
     37                } else if (typeid_rh == symbol_id) {
     38                        return compare_same_type_symbol(
     39                                        static_cast<const symbol*>(lh),
     40                                        static_cast<const symbol*>(rh));
     41                } else if (typeid_rh == power_id) {
     42                        return compare_same_type_power(
     43                                        static_cast<const power*>(lh),
     44                                        static_cast<const power*>(rh));
     45                } else {
     46                        return lh->compare_same_type(*rh);
     47                }
     48        } else if (typeid_lh == fderivative_id) {
     49                //print fderivatives after everything
     50                return -1;
     51        } else if (typeid_lh == function_id) {
     52                //print functions before fderivatives, after anything else
     53                return typeid_rh == fderivative_id ? 1 : -1;
     54        } else if (typeid_lh == mul_id) {
     55                if (typeid_rh == power_id) {
     56                        return compare_mul_power(
     57                                        static_cast<const mul*>(lh),
     58                                        static_cast<const power*>(rh));
     59                } else if (typeid_rh == symbol_id) {
     60                        return compare_mul_symbol(
     61                                        static_cast<const mul*>(lh),
     62                                        static_cast<const symbol*>(rh));
     63                }
     64        } else if (typeid_lh == power_id) {
     65                if (typeid_rh == mul_id) {
     66                        return -compare_mul_power(
     67                                        static_cast<const mul*>(rh),
     68                                        static_cast<const power*>(lh));
     69                } else if (typeid_rh == symbol_id) {
     70                        return compare_power_symbol(
     71                                        static_cast<const power*>(lh),
     72                                        static_cast<const symbol*>(rh));
     73                }
     74        } else if (typeid_lh == symbol_id) {
     75                if (typeid_rh == mul_id) {
     76                        return -compare_mul_symbol(
     77                                        static_cast<const mul*>(rh),
     78                                        static_cast<const symbol*>(lh));
     79                } else if (typeid_rh == power_id) {
     80                        return -compare_power_symbol(
     81                                        static_cast<const power*>(rh),
     82                                        static_cast<const symbol*>(lh));
     83                }
     84        }
     85        //std::cout<<"comparing typeid's"<<std::endl;
     86        return (typeid_lh<typeid_rh ? 1 : -1);
     87}
     88
     89int ex_is_greater_degrevlex::compare_mul_symbol(const mul *lh,
     90                const symbol *rh) const
     91{
     92        int cmpval;
     93        double tdeg;
     94        tdeg = lh->total_degree();
     95        if (tdeg == 1) {
     96                cmpval = compare(get_pointer(lh->seq[0].rest.bp), rh);
     97                if (cmpval != 0) {
     98                        return cmpval;
     99                }
     100                cmpval = compare(_num1_p,
     101                                get_pointer(lh->seq[0].coeff.bp));
     102                if (cmpval != 0) {
     103                        return cmpval;
     104                }
     105                return -1;
     106        }
     107        return tdeg > 1 ? 1 : -1;
     108}
     109
     110// compare this to a pow object
     111// first we compare degrees
     112// if equal we compare the first item in the sequence to the base in other
     113int ex_is_greater_degrevlex::compare_mul_power(const mul *lh,
     114                const power *rh) const
     115{
     116        double lh_deg = lh->total_degree();
     117        double rh_deg;
     118        numeric rh_exp;
     119        int cmpval = 0;
     120        if (is_a<numeric>(rh->exponent)) {
     121                rh_exp = ex_to<numeric>(rh->exponent);
     122                if (rh_exp.is_real()) {
     123                        rh_deg = rh_exp.to_double();
     124                } else {
     125                        rh_deg = std::sqrt(std::pow(rh_exp.real().to_double(), 2) +
     126                                        std::pow(rh_exp.imag().to_double(), 2));
     127                }
     128                if (rh_deg != lh_deg)
     129                        return lh_deg < rh_deg ? -1 : 1;
     130        } else {
     131                cmpval = compare(get_pointer(lh->seq[0].coeff.bp),
     132                                get_pointer(rh->exponent.bp));
     133                if (cmpval != 0)
     134                        return cmpval;
     135        }
     136        cmpval = compare(get_pointer(lh->seq[0].rest.bp),
     137                        get_pointer(rh->basis.bp));
     138        if (cmpval != 0) {
     139                return cmpval;
     140        }
     141        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     142                return 0;
     143        return 1;
     144}
     145
     146int ex_is_greater_degrevlex::compare_same_type_mul(const mul *lh,
     147                const mul *rh) const
     148{
     149        int cmpval;
     150
     151        // compare total degrees
     152        double lh_deg = lh->total_degree();
     153        double rh_deg = rh->total_degree();
     154        if (lh_deg != rh_deg)
     155                return lh_deg < rh_deg ? -1 : 1;
     156
     157        // compare each item in lh to corresponding element in rh
     158        epvector::const_iterator cit1 = lh->seq.begin();
     159        epvector::const_iterator cit2 = rh->seq.begin();
     160        epvector::const_iterator last1 = lh->seq.end();
     161        epvector::const_iterator last2 = rh->seq.end();
     162
     163        for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
     164                cmpval = ( cit1->compare(*cit2));
     165                if (cmpval != 0)
     166                        return cmpval;
     167        }
     168
     169        // compare sizes
     170        if (cit1 != last1)
     171                return 1;
     172        else if (cit2 != last2)
     173                return -1;
     174
     175        // compare overall_coeff
     176        cmpval = compare(get_pointer(lh->overall_coeff.bp),
     177                        get_pointer(rh->overall_coeff.bp));
     178        if (cmpval!=0)
     179                return cmpval;
     180
     181        return 0;
     182}
     183
     184int ex_is_greater_degrevlex::compare_same_type_add(const add *lh,
     185                const add *rh) const
     186{
     187        int cmpval;
     188
     189        // compare number of elements
     190        if (lh->seq.size() != rh->seq.size())
     191                return (lh->seq.size()<rh->seq.size()) ? -1 : 1;
     192
     193        epvector::const_iterator cit1 = lh->seq.begin();
     194        epvector::const_iterator cit2 = rh->seq.begin();
     195        epvector::const_iterator last1 = lh->seq.end();
     196        epvector::const_iterator last2 = rh->seq.end();
     197
     198        for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
     199                cmpval = compare(get_pointer(cit2->rest.bp),
     200                                get_pointer(cit1->rest.bp));
     201                if (cmpval!=0) return cmpval;
     202        }
     203
     204        GINAC_ASSERT(cit1==last1);
     205        GINAC_ASSERT(cit2==last2);
     206
     207        // compare overall_coeff
     208        cmpval = compare(get_pointer(lh->overall_coeff.bp),
     209                        get_pointer(rh->overall_coeff.bp));
     210        if (cmpval!=0)
     211                return cmpval;
     212
     213        return 0;
     214}
     215
     216int ex_is_greater_degrevlex::compare_power_symbol(const power *lh,
     217                const symbol *rh) const
     218{
     219        //std::cout<<"in compare_power_symbol"<<std::endl;
     220        int cmpval;
     221        cmpval = compare(get_pointer(lh->exponent.bp), _num1_p);
     222        if (cmpval != 0) {
     223                return cmpval;
     224        }
     225        return compare(get_pointer(lh->basis.bp), rh);
     226}
     227
     228int ex_is_greater_degrevlex::compare_same_type_power(const power *lh,
     229                const power *rh) const
     230{
     231        int cmpval = compare(get_pointer(lh->exponent.bp),
     232                                get_pointer(rh->exponent.bp));
     233        if (cmpval)
     234                return cmpval;
     235        else
     236                return compare(get_pointer(lh->basis.bp),
     237                        get_pointer(rh->basis.bp));
     238}
     239
     240int ex_is_greater_degrevlex::compare_same_type_symbol(const symbol *lh,
     241                const symbol *rh) const
     242{
     243        //std::cout<<"in compare_same symbol"<<std::endl;
     244        //std::cout<<"lh: ";
     245        //lh->dbgprint();
     246        //std::cout<<"rh: ";
     247        //rh->dbgprint();
     248        //std::cout<<std::endl;
     249        if (lh->serial==rh->serial) return 0;
     250        //std::cout<<"after if"<<std::endl;
     251
     252// SAGE/Pynac: Sorting based on creation order doesn't work for Sage.
     253// instead we sort on variable name. -- William Stein
     254
     255        //std::cout<<"comparing names: "<<(lh->name < rh->name)<<std::endl;
     256        return lh->name < (rh->name) ? 1 : -1;
     257}
     258
     259} // namespace GiNaC
  • new file ginac/order.h

    diff --git a/ginac/order.h b/ginac/order.h
    new file mode 100644
    - +  
     1#include "ex.h"
     2#include "basic.h"
     3#include "mul.h"
     4#include "power.h"
     5#include "add.h"
     6#include "symbol.h"
     7
     8namespace GiNaC {
     9       
     10        struct ex_is_greater_degrevlex : public std::binary_function<ex, ex, bool> {
     11                const tinfo_t function_id;// = find_tinfo_key("function");
     12                const tinfo_t fderivative_id;// = find_tinfo_key("fderivative");
     13                const tinfo_t power_id;// = find_tinfo_key("power");
     14                const tinfo_t symbol_id;// = find_tinfo_key("symbol");
     15                const tinfo_t mul_id;// = find_tinfo_key("mul");
     16                const tinfo_t add_id;// = find_tinfo_key("add");
     17
     18                ex_is_greater_degrevlex():
     19                        function_id(find_tinfo_key("function")),
     20                        fderivative_id(find_tinfo_key("fderivative")),
     21                        power_id(find_tinfo_key("power")),
     22                        symbol_id(find_tinfo_key("symbol")),
     23                        mul_id(find_tinfo_key("mul")),
     24                        add_id(find_tinfo_key("add")) {};
     25                bool operator() (const ex &lh, const ex &rh) const;
     26                int compare(const basic *lh, const basic *rh) const;
     27                int compare_mul_symbol(const mul *lh, const symbol *rh) const;
     28                int compare_mul_power(const mul *lh, const power *rh) const;
     29                int compare_same_type_mul(const mul *lh, const mul *rh) const;
     30                int compare_same_type_add(const add *lh, const add *rh) const;
     31                int compare_power_symbol(const power *lh, const symbol *rh) const;
     32                int compare_same_type_power(const power *lh, const power *rh) const;
     33                int compare_same_type_symbol(const symbol *lh, const symbol *rh) const;
     34        };
     35
     36struct expair_rest_is_greater_degrevlex : public std::binary_function<expair, expair, bool> {
     37        bool operator()(const expair &lh, const expair &rh) const { return ex_is_greater_degrevlex()(lh.rest, rh.rest); }
     38};
     39
     40}
  • ginac/power.cpp

    diff --git a/ginac/power.cpp b/ginac/power.cpp
    a b  
    902902        }
    903903}
    904904
    905 int power::compare(const basic& other) const
    906 {
    907         static const tinfo_t mul_id = find_tinfo_key("mul");
    908         static const tinfo_t symbol_id = find_tinfo_key("symbol");
    909         static const tinfo_t function_id = find_tinfo_key("function");
    910         static const tinfo_t fderivative_id = find_tinfo_key("fderivative");
    911         const tinfo_t typeid_this = tinfo();
    912         const tinfo_t typeid_other = other.tinfo();
    913         if (typeid_this==typeid_other) {
    914                 GINAC_ASSERT(typeid(*this)==typeid(other));
    915                 return compare_same_type(other);
    916         } else if (typeid_other == mul_id) {
    917                 return -static_cast<const mul&>(other).compare_pow(*this);
    918         } else if (typeid_other == symbol_id) {
    919                 return compare_symbol(static_cast<const symbol&>(other));
    920         } else if (typeid_other == function_id ||
    921                         typeid_other == fderivative_id) {
    922                 return -1;
    923         } else {
    924                 return (typeid_this<typeid_other ? -1 : 1);
    925         }
    926 }
    927 
    928 int power::compare_symbol(const symbol & other) const
    929 {
    930         int cmpval;
    931         cmpval = _ex1.compare(exponent);
    932         if (cmpval != 0) {
    933                 return cmpval;
    934         }
    935         return basis.compare(other);
    936 }
    937 
    938905int power::compare_same_type(const basic & other) const
    939906{
    940907        GINAC_ASSERT(is_exactly_a<power>(other));
     
    944911        if (cmpval)
    945912                return cmpval;
    946913        else
    947           // SAGE -- I changed the sign below for consistency with standard
    948           // mathematics and all other math software (except mathematica).
    949           // This makes it so x^5 + x^2 prints correctly instead of
    950           // as x^2 + x^5.   -- William Stein
    951                 return -exponent.compare(o.exponent);
     914                return exponent.compare(o.exponent);
    952915}
    953916
    954917unsigned power::return_type() const
  • ginac/power.h

    diff --git a/ginac/power.h b/ginac/power.h
    a b  
    4040{
    4141        GINAC_DECLARE_REGISTERED_CLASS(power, basic)
    4242       
     43        friend struct ex_is_greater_degrevlex;
    4344        friend class mul;
    4445       
    4546// member functions
     
    7273        ex conjugate() const;
    7374        ex real_part() const;
    7475        ex imag_part() const;
    75         int compare(const basic& other) const;
    76         int compare_symbol(const symbol& other) const;
     76        //int compare(const basic& other) const;
     77        //int compare_symbol(const symbol& other) const;
    7778protected:
    7879        ex derivative(const symbol & s) const;
    7980        ex eval_ncmul(const exvector & v) const;
  • ginac/symbol.cpp

    diff --git a/ginac/symbol.cpp b/ginac/symbol.cpp
    a b  
    280280                return _ex1;
    281281}
    282282
     283/*
    283284int symbol::compare(const basic& other) const
    284285{
    285286        static const tinfo_t pow_id = find_tinfo_key("power");
     
    302303                return (typeid_this<typeid_other ? -1 : 1);
    303304        }
    304305}
     306*/
    305307
    306308int symbol::compare_same_type(const basic & other) const
    307309{
    308310        GINAC_ASSERT(is_a<symbol>(other));
    309311        const symbol *o = static_cast<const symbol *>(&other);
    310312        if (serial==o->serial) return 0;
    311        
    312         // SAGE/Pynac: Sorting based on creation order doesn't work for Sage.
    313         // instead we sort on variable name. -- William Stein
    314 
    315         return name < (o->name) ? -1 : 1;
    316        
    317         // This is what Ginac used to return.  It fits with their
    318         // philosophy that symbols names have no intrinsic meaning,
    319         // only the order of creation of symbols matters.  Also, they
    320         // allow multiple symbols with the same name.  Our Pynac
    321         // wrapper does not allow for this, and we find the behavior
    322         // way too confusing and ad hoc with this convention.
    323 
    324         // return serial < o->serial ? -1 : 1;
     313        return serial < o->serial ? -1 : 1;
    325314}
    326315
    327316bool symbol::is_equal_same_type(const basic & other) const
  • ginac/symbol.h

    diff --git a/ginac/symbol.h b/ginac/symbol.h
    a b  
    4343
    4444        friend class realsymbol;
    4545        friend class possymbol;
     46        friend struct ex_is_greater_degrevlex;
    4647
    4748// types
    4849       
     
    5859       
    5960        // functions overriding virtual functions from base classes
    6061public:
    61         //      int compare_same_type(const basic & other) const;
    62         int compare(const basic &other) const;
     62        //int compare_same_type(const basic & other) const;
     63        //int compare(const basic &other) const;
    6364        bool info(unsigned inf) const;
    6465        ex eval(int level = 0) const;
    6566        ex evalf(int level = 0) const { return *this; } // overwrites basic::evalf() for performance reasons