Ticket #9880: trac_9880-pynac_order_jp_new-p2.patch

File trac_9880-pynac_order_jp_new-p2.patch, 40.4 KB (added by jpflori, 9 years ago)

New version of patch, apply after burcin original one to build updated spkg

  • ginac/basic.cpp

    # HG changeset patch
    # User Jean-Pierre Flori <flori@enst.fr>
    # Date 1299143384 -3600
    # Node ID 67bdc3eefa160482ccbef431db334ee49159764f
    # Parent  a8d8d201814186823ebc1204f5acf55e0b8b5b91
    Fixes to printing order.
    
    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/basic.cpp
    a b  
    829829 *  1 greater. */
    830830int basic::compare(const basic & other) const
    831831{
    832  #ifdef GINAC_COMPARE_STATISTICS
     832#ifdef GINAC_COMPARE_STATISTICS
    833833        compare_statistics.total_basic_compares++;
    834834#endif
    835835        const unsigned hash_this = gethash();
  • ginac/basic.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/basic.h
    a b  
    109109       
    110110        friend class ex;
    111111        friend struct ex_is_greater_degrevlex;
    112        
     112        friend struct expair_is_greater_degrevlex;
    113113        // default constructor, destructor, copy constructor and assignment operator
    114114protected:
    115115        basic() : tinfo_key(&tinfo_static), flags(0) {}
  • ginac/container.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/container.h
    a b  
    129129class container : public basic, public container_storage<C> {
    130130        GINAC_DECLARE_REGISTERED_CLASS(container, basic)
    131131
     132        friend struct ex_is_greater_degrevlex;
     133
    132134protected:
    133135        typedef typename container_storage<C>::STLT STLT;
    134136
  • ginac/ex.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/ex.h
    a b  
    7979        template<class T> friend inline bool is_exactly_a(const ex &);
    8080       
    8181        friend struct ex_is_greater_degrevlex;
     82        friend struct expair_is_greater_degrevlex;
    8283        // default constructor, copy constructor and assignment operator
    8384public:
    8485        ex() throw();
  • ginac/expairseq.cpp

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/expairseq.cpp
    a b  
    11901190                seq_sorted = new epvector(seq.size());
    11911191                partial_sort_copy(seq.begin(), seq.end(),
    11921192                                seq_sorted->begin(), seq_sorted->end(),
    1193                                 expair_rest_is_greater_degrevlex());
     1193                                  expair_is_greater_degrevlex::in_type(tinfo()));
    11941194        }
    11951195        return seq_sorted;
    11961196}
  • ginac/expairseq.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/expairseq.h
    a b  
     1
    12/** @file expairseq.h
    23 *
    34 *  Interface to sequences of expression pairs. */
     
    3839 *  combining n terms into one large sum (or n terms into one large product)
    3940 *  from O(n*log(n)) to about O(n).  There are, however, several drawbacks.
    4041 *  The constant in front of O(n) is quite large, when copying such an object
    41  *  one also has to copy the has table, comparison is quite expensive because
     42 *  one also has to copy the hash table, comparison is quite expensive because
    4243 *  there is no ordering any more, it doesn't help at all when combining two
    4344 *  expairseqs because due to the presorted nature the behaviour would be
    4445 *  O(n) anyways, the code is quite messy, etc, etc.  The code is here as
     
    133134        void make_flat(const epvector & v, bool do_index_renaming = false);
    134135        void canonicalize();
    135136        void combine_same_terms_sorted_seq();
     137        epvector* get_sorted_seq() const;
    136138#if EXPAIRSEQ_USE_HASHTAB
    137139        void combine_same_terms();
    138140        unsigned calc_hashtabsize(unsigned sz) const;
     
    159161        std::auto_ptr<epvector> evalchildren(int level) const;
    160162        std::auto_ptr<epvector> subschildren(const exmap & m, unsigned options = 0) const;
    161163       
    162         epvector* get_sorted_seq() const;
    163164// member variables
    164165       
    165166protected:
  • ginac/fderivative.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/fderivative.h
    a b  
    4040{
    4141        GINAC_DECLARE_REGISTERED_CLASS(fderivative, function)
    4242
     43        friend struct ex_is_greater_degrevlex;
    4344        // other constructors
    4445public:
    4546        /** Construct derivative with respect to one parameter.
  • ginac/function.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/function.h
    a b  
    310310{
    311311        GINAC_DECLARE_REGISTERED_CLASS(function, exprseq)
    312312
     313        friend struct ex_is_greater_degrevlex;
    313314        // CINT has a linking problem
    314315#ifndef __MAKECINT__
    315316        friend void ginsh_get_ginac_functions();
  • ginac/mul.cpp

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/mul.cpp
    a b  
    3333#include "constant.h"
    3434#include "function.h"
    3535#include "inifcns.h"
     36#include "order.h"
    3637
    3738#include <iostream>
    3839#include <vector>
     
    5556// default constructor
    5657//////////
    5758
    58 mul::mul()
     59mul::mul() : texponent(NULL)
    5960{
    6061        tinfo_key = &mul::tinfo_static;
    6162}
     
    6667
    6768// public
    6869
    69 mul::mul(const ex & lh, const ex & rh)
     70mul::mul(const ex & lh, const ex & rh) : texponent(NULL)
    7071{
    7172        tinfo_key = &mul::tinfo_static;
    7273        overall_coeff = _ex1;
     
    7475        GINAC_ASSERT(is_canonical());
    7576}
    7677
    77 mul::mul(const exvector & v, bool hold)
     78mul::mul(const exvector & v, bool hold) : texponent(NULL)
    7879{
    7980        tinfo_key = &mul::tinfo_static;
    8081        overall_coeff = _ex1;
     
    8283        GINAC_ASSERT(is_canonical());
    8384}
    8485
    85 mul::mul(const epvector & v)
     86mul::mul(const epvector & v) : texponent(NULL)
    8687{
    8788        tinfo_key = &mul::tinfo_static;
    8889        overall_coeff = _ex1;
     
    9091        GINAC_ASSERT(is_canonical());
    9192}
    9293
    93 mul::mul(const epvector & v, const ex & oc, bool do_index_renaming)
     94mul::mul(const epvector & v, const ex & oc, bool do_index_renaming) : texponent(NULL)
    9495{
    9596        tinfo_key = &mul::tinfo_static;
    9697        overall_coeff = oc;
     
    9899        GINAC_ASSERT(is_canonical());
    99100}
    100101
    101 mul::mul(std::auto_ptr<epvector> vp, const ex & oc, bool do_index_renaming)
     102mul::mul(std::auto_ptr<epvector> vp, const ex & oc, bool do_index_renaming) : texponent(NULL)
    102103{
    103104        tinfo_key = &mul::tinfo_static;
    104105        GINAC_ASSERT(vp.get()!=0);
     
    107108        GINAC_ASSERT(is_canonical());
    108109}
    109110
    110 mul::mul(const ex & lh, const ex & mh, const ex & rh)
     111mul::mul(const ex & lh, const ex & mh, const ex & rh) : texponent(NULL)
    111112{
    112113        tinfo_key = &mul::tinfo_static;
    113114        exvector factors;
     
    11871188        return (new add(addseq))->setflag(status_flags::dynallocated);
    11881189}
    11891190
     1191/** Total degree of a mul object.
     1192 Beware that symbolic exponents are wrapped inside pow objects with 1 as coeff. */
    11901193double mul::total_degree() const
    11911194{
    11921195        if (flags & status_flags::tdegree_calculated) {
     
    12011204        setflag(status_flags::tdegree_calculated);
    12021205        return tdegree;
    12031206}
     1207/** Compute total exponent of a mul object.
     1208    We extract all wrapped level of exponents of power objects. */
     1209ex* mul::get_total_exponent() const
     1210{
     1211        if (!this->texponent) {
     1212                size_t num = seq.size();
     1213                exvector addseq;
     1214                addseq.reserve(num);
     1215                ex exponent;
     1216                epvector::const_iterator i = seq.begin(), end = seq.end();
     1217                for (; i != end; ++i) {
     1218                  // this does just one level
     1219                        if (is_a<power>(i->rest))
     1220                                exponent = (new mul(i->coeff,ex_to<power>(i->rest).exponent))->setflag(status_flags::dynallocated);
     1221                        else
     1222                                exponent = i->coeff;
     1223                        addseq.push_back(exponent);
     1224                }
     1225                texponent = new ex((new add(addseq))->setflag(status_flags::dynallocated));
     1226        }
     1227        return texponent;
     1228}
    12041229
    12051230/*
    12061231int mul::compare(const basic& other) const
  • ginac/mul.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/mul.h
    a b  
    3333{
    3434        GINAC_DECLARE_REGISTERED_CLASS(mul, expairseq)
    3535       
     36        friend struct ex_is_greater_degrevlex;
    3637        friend class add;
    3738        friend class ncmul;
    3839        friend class power;
     
    9293public:
    9394        ex algebraic_subs_mul(const exmap & m, unsigned options) const;
    9495        double total_degree() const;
     96        ex* get_total_exponent() const;
     97
    9598        //int compare_symbol(const symbol &other) const;
    9699        //int compare_pow(const power &other) const;
    97100protected:
     
    108111        static bool can_be_further_expanded(const ex & e);
    109112        std::auto_ptr<epvector> expandchildren(unsigned options) const;
    110113
     114        mutable ex *texponent;
    111115        mutable double tdegree;
    112116};
    113117
  • ginac/numeric.cpp

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/numeric.cpp
    a b  
    236236        return x.v._pyobject;
    237237
    238238      default:
     239        std::cout << x.t <<std::endl;
    239240        stub("Number_T_to_pyobject -- not able to do conversion to pyobject; everything else will be nonsense");
    240241        return 0;
    241242      }
  • ginac/numeric.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/numeric.h
    a b  
    207207  class numeric : public basic
    208208  {
    209209    GINAC_DECLARE_REGISTERED_CLASS(numeric, basic)
    210        
     210    //friend struct expair_is_greater_degrevlex;
    211211    // member functions
    212212       
    213213    // other constructors
  • ginac/order.cpp

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/order.cpp
    a b  
     1/** @file order.cpp
     2 *
     3 *  Definitions of order used for printing. */
     4
     5/*
     6 *  GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany
     7 *
     8 *  This program is free software; you can redistribute it and/or modify
     9 *  it under the terms of the GNU General Public License as published by
     10 *  the Free Software Foundation; either version 2 of the License, or
     11 *  (at your option) any later version.
     12 *
     13 *  This program is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 *  GNU General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU General Public License
     19 *  along with this program; if not, write to the Free Software
     20 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     21 */
    122
    223#include "order.h"
    324#include "registrar.h"
     
    829
    930namespace GiNaC {
    1031
     32/** What SAGE does for printing:
     33 To print multivariate polynomials, SAGE uses "reversed" (bigger terms first) 'degrevlex' order
     34 i.e. "reversed" graded reversed lexicographic order, the lexicographic order is defined below.
     35 The variables are ordered according to their "creation" order
     36 i.e PR.<x,a,t> = PolynomialRing(QQ) gives x > a > t
     37 and x+t+a is printed x + a + t
     38*/
    1139
     40/** Returns true if lhex > rhex for 'degrevlex' of SAGE
     41 i.e. graded reversed lexicographic order
     42*/
    1243bool ex_is_greater_degrevlex::operator() (const ex &lhex, const ex &rhex) const {
    13         //std::cout<<"in ex_is_greater_degrevlex::operator()"<<std::endl;
     44        //std::cout<<"in ex_is_greater_degrevlex::operator()"<<std::endl;
    1445        //std::cout<<"lh: ";
    1546        //lhex.dbgprint();
    1647        //std::cout<<std::endl<<"rh: ";
    1748        //rhex.dbgprint();
    1849        //std::cout<<std::endl;
    19         const basic *lh = get_pointer(lhex.bp); 
     50        const basic *lh = get_pointer(lhex.bp);
    2051        const basic *rh = get_pointer(rhex.bp);
    2152        return compare(lh, rh) == 1;
    2253}
    2354
     55int ex_is_greater_degrevlex::compare (const ex &lhex, const ex &rhex) const {
     56        const basic *lh = get_pointer(lhex.bp);
     57        const basic *rh = get_pointer(rhex.bp);
     58        return compare(lh, rh);
     59}
     60
     61bool expair_is_greater_degrevlex::operator() (const expair &lhex, const expair &rhex) const
     62{
     63        const basic *lh = get_pointer(lhex.rest.bp);
     64        const basic *rh = get_pointer(rhex.rest.bp);
     65
     66        // compare rests
     67        int cmpval = ex_is_greater_degrevlex::in_type(in_type_id).compare(lh, rh);
     68        if (cmpval != 0) {
     69                return cmpval == 1;
     70        }
     71
     72        // compare coeffs which are numerics
     73        //std::cout << "comparing coeffs" << std::endl;
     74        //lhex.coeff.bp->dbgprinttree();
     75        //rhex.coeff.bp->dbgprinttree();
     76        numeric lh_coeff = ex_to<numeric>(lhex.coeff);
     77        numeric rh_coeff = ex_to<numeric>(rhex.coeff);
     78        // strange...
     79        //std::cout<<lh->compare_same_type(rh)<<std::endl;
     80        //return lh->compare_same_type(rh) == 1;
     81        double lh_deg = 1;
     82        double rh_deg = 1;
     83                if (lh_coeff.is_real()) {
     84                        lh_deg = lh_coeff.to_double();
     85                } else {
     86                        lh_deg = std::sqrt(std::pow(lh_coeff.real().to_double(), 2) +
     87                                        std::pow(lh_coeff.imag().to_double(), 2));
     88                }
     89                if (rh_coeff.is_real()) {
     90                        rh_deg = rh_coeff.to_double();
     91                } else {
     92                        rh_deg = std::sqrt(std::pow(rh_coeff.real().to_double(), 2) +
     93                                        std::pow(rh_coeff.imag().to_double(), 2));
     94                }
     95
     96        return lh_deg > rh_deg;
     97}
     98
     99/** Comparison functions:
     100 They should implement 'degrevlex' of SAGE
     101 i.e. graded reversed lexicographic order
     102 The lexicographic order should depend on the "creation" order of variables ?
     103 Or should it be a "natural" one on strings : a > b > ... > x > y > ... ?
     104*/
     105
     106/** Return values for comparison functions :
     107 compare(a,b) should return :
     108 -1 if a < b
     109 0 if a == b
     110 1 if a > b
     111 as <=> in Perl and GiNaC internal functions
     112*/
     113
    24114int ex_is_greater_degrevlex::compare(const basic *lh, const basic *rh) const {
    25115        const tinfo_t typeid_lh = lh->tinfo();
    26116        const tinfo_t typeid_rh = rh->tinfo();
     
    42132                        return compare_same_type_power(
    43133                                        static_cast<const power*>(lh),
    44134                                        static_cast<const power*>(rh));
     135                } else if (typeid_rh == function_id) {
     136                        return compare_same_type_function(
     137                                        static_cast<const function*>(lh),
     138                                        static_cast<const function*>(rh));
     139                } else if (typeid_rh == fderivative_id) {
     140                        return compare_same_type_fderivative(
     141                                        static_cast<const fderivative*>(lh),
     142                                        static_cast<const fderivative*>(rh));
    45143                } else {
     144                        // using GiNaC functions by default
    46145                        return lh->compare_same_type(*rh);
    47146                }
     147        // at present numerics are combined into overall_coefficient
     148        // even when hold parameter is used
     149        } else if (typeid_lh == numeric_id) {
     150                //print numerics after anything else
     151                return -1;
     152        } else if (typeid_rh == numeric_id) {
     153                //print numerics after anything else
     154                return 1;
     155        } else if (typeid_lh == constant_id) {
     156                //print constants after anything else
     157                return -1;
     158        } else if (typeid_rh == constant_id) {
     159                //print constants after anything else
     160                return 1;
    48161        } else if (typeid_lh == fderivative_id) {
    49                 //print fderivatives after everything
     162                //print fderivatives after everything else
    50163                return -1;
     164        } else if (typeid_rh == fderivative_id) {
     165                //print fderivatives after everything esle
     166                return 1;
    51167        } else if (typeid_lh == function_id) {
    52168                //print functions before fderivatives, after anything else
    53                 return typeid_rh == fderivative_id ? 1 : -1;
     169                return -1;
     170        } else if (typeid_rh == function_id) {
     171                //print functions before fderivatives, after anything else
     172                return 1;
    54173        } else if (typeid_lh == mul_id) {
    55174                if (typeid_rh == power_id) {
    56175                        return compare_mul_power(
     
    60179                        return compare_mul_symbol(
    61180                                        static_cast<const mul*>(lh),
    62181                                        static_cast<const symbol*>(rh));
     182                } else if (typeid_rh == add_id) {
     183                        return -compare_add_mul(
     184                                        static_cast<const add*>(rh),
     185                                        static_cast<const mul*>(lh));
     186                }
     187        } else if (typeid_lh == add_id) {
     188                if (typeid_rh == power_id) {
     189                        return compare_add_power(
     190                                        static_cast<const add*>(lh),
     191                                        static_cast<const power*>(rh));
     192                } else if (typeid_rh == symbol_id) {
     193                        return compare_add_symbol(
     194                                        static_cast<const add*>(lh),
     195                                        static_cast<const symbol*>(rh));
     196                } else if (typeid_rh == mul_id) {
     197                        return compare_add_mul(
     198                                        static_cast<const add*>(lh),
     199                                        static_cast<const mul*>(rh));
    63200                }
    64201        } else if (typeid_lh == power_id) {
    65202                if (typeid_rh == mul_id) {
    66203                        return -compare_mul_power(
    67204                                        static_cast<const mul*>(rh),
    68205                                        static_cast<const power*>(lh));
     206                } else if (typeid_rh == add_id) {
     207                        return -compare_add_power(
     208                                        static_cast<const add*>(rh),
     209                                        static_cast<const power*>(lh));
    69210                } else if (typeid_rh == symbol_id) {
    70211                        return compare_power_symbol(
    71212                                        static_cast<const power*>(lh),
     
    76217                        return -compare_mul_symbol(
    77218                                        static_cast<const mul*>(rh),
    78219                                        static_cast<const symbol*>(lh));
     220                } else if (typeid_rh == add_id) {
     221                        return -compare_add_symbol(
     222                                        static_cast<const add*>(rh),
     223                                        static_cast<const symbol*>(lh));
    79224                } else if (typeid_rh == power_id) {
    80225                        return -compare_power_symbol(
    81226                                        static_cast<const power*>(rh),
    82227                                        static_cast<const symbol*>(lh));
    83228                }
    84         }
    85         //std::cout<<"comparing typeid's"<<std::endl;
    86         return (typeid_lh<typeid_rh ? 1 : -1);
     229        }
     230        std::cout<<"comparing typeid's"<<std::endl;
     231        return (typeid_lh<typeid_rh ? -1 : 1);
    87232}
    88233
     234// compare a mul and a symbol objects
     235// same behavior within mul and add objects:
     236// the total degree of the symbol is 1
     237// check total degree of mul then compare smallest item to symbol
    89238int ex_is_greater_degrevlex::compare_mul_symbol(const mul *lh,
    90239                const symbol *rh) const
    91240{
     241  //std::cout<<"comparing mul and symbol"<<std::endl;
     242  //lh->dbgprint();
     243  //rh->dbgprint();
    92244        int cmpval;
     245
    93246        double tdeg;
    94247        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;
     248
     249        if (tdeg != 1)
     250                return tdeg > 1 ? 1 : -1;
     251       
     252        const expair smallest_item = lh->get_sorted_seq()->back();
     253
     254        // compare bases
     255        cmpval = compare(get_pointer(smallest_item.rest.bp), rh);
     256        if (cmpval != 0) {
     257                return cmpval;
    106258        }
    107         return tdeg > 1 ? 1 : -1;
     259
     260        // compare exponents
     261        cmpval = -compare(get_pointer(smallest_item.coeff.bp),_num1_p);
     262        if (cmpval != 0) {
     263                return cmpval;
     264        }
     265
     266        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     267                return 0;
     268
     269        // there is something of total degree 0 in front of the mul object
     270        return 1;
    108271}
    109272
    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
     273
     274// compare a mul and a pow objects
     275// same behavior wihtin mul and add objects:
     276// first we compare total degrees
     277// if equal we compare the smallest basis in the sequence to the basis in other
     278// then their exponents
    113279int ex_is_greater_degrevlex::compare_mul_power(const mul *lh,
    114280                const power *rh) const
    115281{
     282        int cmpval;
     283
    116284        double lh_deg = lh->total_degree();
    117         double rh_deg;
     285        double rh_deg = 1;
    118286        numeric rh_exp;
    119         int cmpval = 0;
    120287        if (is_a<numeric>(rh->exponent)) {
    121288                rh_exp = ex_to<numeric>(rh->exponent);
    122289                if (rh_exp.is_real()) {
     
    125292                        rh_deg = std::sqrt(std::pow(rh_exp.real().to_double(), 2) +
    126293                                        std::pow(rh_exp.imag().to_double(), 2));
    127294                }
    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;
    135295        }
    136         cmpval = compare(get_pointer(lh->seq[0].rest.bp),
     296        if (rh_deg != lh_deg)
     297                return lh_deg < rh_deg ? -1 : 1;
     298        // same total degree
     299
     300        // smallest item is at the end of the sorted sequence
     301        const expair smallest_item = lh->get_sorted_seq()->back();
     302       
     303        // compare bases
     304        cmpval = compare(get_pointer(smallest_item.rest.bp),
    137305                        get_pointer(rh->basis.bp));
    138306        if (cmpval != 0) {
    139307                return cmpval;
    140308        }
    141         if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
    142                 return 0;
     309
     310        // compare exponents
     311        cmpval = -compare(get_pointer(smallest_item.coeff.bp),
     312                        get_pointer(rh->exponent.bp));
     313        if (cmpval != 0) {
     314                return cmpval;
     315        }
     316
     317        // there is something of total degree 0 in front of the mul object
    143318        return 1;
    144319}
    145320
     321// compare two mul objects
     322// same behavior wihtin mul and add objects:
     323// first we compare total degrees
     324// if equal we compare the basis of the smallest items
     325// then their exponents
     326// and so on
    146327int ex_is_greater_degrevlex::compare_same_type_mul(const mul *lh,
    147328                const mul *rh) const
    148329{
     330  //std::cout<<"comparing mul and mul"<<std::endl;
     331  //lh->dbgprint();
     332  //rh->dbgprint();
    149333        int cmpval;
    150 
     334       
    151335        // compare total degrees
    152336        double lh_deg = lh->total_degree();
    153337        double rh_deg = rh->total_degree();
     338        //std::cout<<"degree "<<lh_deg<<" and "<<rh_deg<<std::endl;
    154339        if (lh_deg != rh_deg)
    155340                return lh_deg < rh_deg ? -1 : 1;
    156 
     341       
    157342        // 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();
     343        const epvector *sorted_seq1 = lh->get_sorted_seq();
     344        const epvector *sorted_seq2 = rh->get_sorted_seq();
     345        epvector::const_reverse_iterator cit1 = sorted_seq1->rbegin();
     346        epvector::const_reverse_iterator cit2 = sorted_seq2->rbegin();
     347        epvector::const_reverse_iterator last1 = sorted_seq1->rend();
     348        epvector::const_reverse_iterator last2 = sorted_seq2->rend();
    162349
    163350        for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
    164                 cmpval = ( cit1->compare(*cit2));
    165                 if (cmpval != 0)
     351                // compare bases
     352                cmpval = compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
     353                if (cmpval != 0) {
    166354                        return cmpval;
     355                }
     356
     357                // compare exponents
     358                cmpval = -compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
     359                if (cmpval != 0) {
     360                        return cmpval;
     361                }
    167362        }
    168363
    169364        // compare sizes
     
    181376        return 0;
    182377}
    183378
     379// compare an add and a symbol objects
     380// same behavior wihtin mul and add objects:
     381// the coefficient of the symbol is 1
     382int ex_is_greater_degrevlex::compare_add_symbol(const add *lh,
     383                const symbol *rh) const
     384{
     385  //std::cout<<"comparing add and symbol"<<std::endl;
     386  //lh->dbgprint();
     387  //rh->dbgprint();
     388        int cmpval;
     389
     390        const expair biggest_item = lh->get_sorted_seq()->front();
     391
     392        // compare bases
     393        cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(biggest_item.rest.bp), rh);
     394        if (cmpval != 0) {
     395                return cmpval;
     396        }
     397
     398        // compare coefficients
     399        cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
     400        if (cmpval != 0) {
     401                return cmpval;
     402        }
     403
     404        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     405                return 0;
     406
     407        // there is something at the end of the add object
     408        return 1;
     409}
     410
     411// compare an add and a mul objects
     412// same behavior within mul and add objects:
     413// the coefficient of the mul object is 1
     414int ex_is_greater_degrevlex::compare_add_mul(const add *lh,
     415                const mul *rh) const
     416{
     417        int cmpval;
     418        const expair biggest_item = lh->get_sorted_seq()->front();
     419
     420        // compare bases
     421        cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(biggest_item.rest.bp), rh);
     422        if (cmpval != 0) {
     423                return cmpval;
     424        }
     425
     426        // compare coefficients
     427        cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
     428        if (cmpval != 0) {
     429                return cmpval;
     430        }
     431
     432        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     433                return 0;
     434
     435        // there is something at the end of the object
     436        return 1;
     437}
     438
     439// compare an add and a pow objects
     440// same behavior wihtin mul and add objects:
     441// the coefficient of the power object is 1
     442int ex_is_greater_degrevlex::compare_add_power(const add *lh,
     443                const power *rh) const
     444{
     445        int cmpval;
     446        const expair biggest_item = lh->get_sorted_seq()->front();
     447
     448        // compare bases
     449        cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(biggest_item.rest.bp), rh);
     450        if (cmpval != 0) {
     451                return cmpval;
     452        }
     453
     454        // compare coefficients
     455        cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
     456        if (cmpval != 0) {
     457                return cmpval;
     458        }
     459
     460        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     461                return 0;
     462
     463        // there is something at the end of the object
     464        return 1;
     465}
     466
     467// compare two add objects
     468// same behavior wihtin mul and add objects:
     469// first we compare the basis of the biggest items
     470// then their coefficients
     471// and so on
    184472int ex_is_greater_degrevlex::compare_same_type_add(const add *lh,
    185473                const add *rh) const
    186474{
    187475        int cmpval;
    188476
    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();
     477        const epvector *sorted_seq1 = lh->get_sorted_seq();
     478        const epvector *sorted_seq2 = rh->get_sorted_seq();
     479        epvector::const_iterator cit1 = sorted_seq1->begin();
     480        epvector::const_iterator cit2 = sorted_seq2->begin();
     481        epvector::const_iterator last1 = sorted_seq1->end();
     482        epvector::const_iterator last2 = sorted_seq2->end();
    197483
    198484        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;
     485                // compare bases
     486                cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
     487                if (cmpval != 0) {
     488                        return cmpval;
     489                }
     490
     491                // compare coefficients
     492                cmpval = compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
     493                if (cmpval != 0) {
     494                        return cmpval;
     495                }
    202496        }
    203497
    204         GINAC_ASSERT(cit1==last1);
    205         GINAC_ASSERT(cit2==last2);
     498        // compare sizes
     499        if (cit1 != last1)
     500                return 1;
     501        else if (cit2 != last2)
     502                return -1;
    206503
    207504        // compare overall_coeff
    208505        cmpval = compare(get_pointer(lh->overall_coeff.bp),
     
    213510        return 0;
    214511}
    215512
     513// compare a power and a symbol objects
     514// does not behave the same way inside add or mul
     515// in mul object:
     516// first we compare bases
     517// then exponents
     518// in add object:
     519// first exponents
     520// then bases
    216521int ex_is_greater_degrevlex::compare_power_symbol(const power *lh,
    217522                const symbol *rh) const
    218523{
     524        int cmpval;
     525
    219526        //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;
     527        if (in_type_id == &mul::tinfo_static) {
     528                cmpval = compare(get_pointer(lh->basis.bp), rh);
     529                if (cmpval != 0)
     530                          return cmpval;
     531               
     532                cmpval = compare(get_pointer(lh->exponent.bp), _num1_p);
     533                if (cmpval != 0)
     534                          return cmpval;
     535                return 0;
    224536        }
    225         return compare(get_pointer(lh->basis.bp), rh);
     537
     538        // We are in an add object
     539        if (is_a<numeric>(lh->exponent)) {
     540                numeric lh_exp = ex_to<numeric>(lh->exponent);
     541                double lh_deg;
     542                if (lh_exp.is_real()) {
     543                        lh_deg = lh_exp.to_double();
     544                } else {
     545                        lh_deg = std::sqrt(std::pow(lh_exp.real().to_double(), 2) +
     546                                        std::pow(lh_exp.imag().to_double(), 2));
     547                }
     548                if (lh_deg != 1)
     549                        return lh_deg < 1 ? -1 : 1;
     550        }
     551
     552        cmpval = compare(get_pointer(lh->basis.bp), rh);
     553        if (cmpval != 0)
     554                return cmpval;
     555       
     556        return 0;
    226557}
    227558
     559// compare two power objects
     560// does not behave the same way inside add or mul
     561// in mul object:
     562// fist we compare bases
     563// then exponents
     564// in add object:
     565// first exponents
     566// then bases
    228567int ex_is_greater_degrevlex::compare_same_type_power(const power *lh,
    229                 const power *rh) const
     568                const power *rh) const
    230569{
    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));
     570        int cmpval;
     571        if (in_type_id == &mul::tinfo_static) {
     572                cmpval = compare(get_pointer(lh->basis.bp), get_pointer(rh->basis.bp));
     573                if (cmpval != 0)
     574                          return cmpval;
     575                cmpval = compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
     576                if (cmpval != 0)
     577                          return cmpval;
     578                return 0;
     579        }
     580
     581        double lh_deg = 1;
     582        double rh_deg = 1;
     583        if (is_a<numeric>(lh->exponent)) {
     584                numeric lh_exp = ex_to<numeric>(lh->exponent);
     585                if (lh_exp.is_real()) {
     586                        lh_deg = lh_exp.to_double();
     587                } else {
     588                        lh_deg = std::sqrt(std::pow(lh_exp.real().to_double(), 2) +
     589                                        std::pow(lh_exp.imag().to_double(), 2));
     590                }
     591        }
     592        if (is_a<numeric>(rh->exponent)) {
     593                numeric rh_exp = ex_to<numeric>(rh->exponent);
     594                if (rh_exp.is_real()) {
     595                        rh_deg = rh_exp.to_double();
     596                } else {
     597                        rh_deg = std::sqrt(std::pow(rh_exp.real().to_double(), 2) +
     598                                        std::pow(rh_exp.imag().to_double(), 2));
     599                }
     600        }
     601        if (rh_deg != lh_deg)
     602                return lh_deg < rh_deg ? -1 : 1;
     603
     604        cmpval = compare(get_pointer(lh->basis.bp),
     605                         get_pointer(rh->basis.bp));
     606        if (cmpval != 0)
     607                return cmpval;
     608
     609        if (is_a<numeric>(lh->exponent) && is_a<numeric>(rh->exponent))
     610                return 0;
     611        return compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
    238612}
    239613
     614// compare two symbol objects
     615// same behavior wihtin mul and add objects:
     616// we compare names
    240617int ex_is_greater_degrevlex::compare_same_type_symbol(const symbol *lh,
    241618                const symbol *rh) const
    242619{
    243         //std::cout<<"in compare_same symbol"<<std::endl;
     620        //std::cout<<"in compare_same symbol"<<std::endl;
    244621        //std::cout<<"lh: ";
    245622        //lh->dbgprint();
    246623        //std::cout<<"rh: ";
    247624        //rh->dbgprint();
    248625        //std::cout<<std::endl;
     626
     627        // Weird because Sage sorts based on creation order.
     628        // SAGE/Pynac: Sorting based on creation order doesn't work for Sage.
     629        // instead we sort on variable name. -- William Stein
     630
     631        //std::cout<<"comparing names: "<<(lh->name < rh->name)<<std::endl;
     632        /* Reversed ordering on char encoding (i.e. "a" < "b") then length (i.e. "abc" < "abcd")
     633           i.e. "x" > "y" and "xyz" > "xyzt" */
    249634        if (lh->serial==rh->serial) return 0;
    250635        //std::cout<<"after if"<<std::endl;
     636        return lh->name < rh->name ? 1 : -1;
    251637
    252 // SAGE/Pynac: Sorting based on creation order doesn't work for Sage.
    253 // instead we sort on variable name. -- William Stein
     638        //return lh->serial < rh->serial ? 1 : -1;
     639        //return -lh->compare_same_type(*rh);
     640}
    254641
    255         //std::cout<<"comparing names: "<<(lh->name < rh->name)<<std::endl;
    256         return lh->name < (rh->name) ? 1 : -1;
     642// compare two containers of the same type
     643template <template <class T, class = std::allocator<T> > class C>
     644int ex_is_greater_degrevlex::compare_same_type_container(const container<C> *lh,
     645                                                         const container<C> *rh) const
     646{
     647        typename C<ex>::const_iterator it1 = lh->seq.begin(), it1end = lh->seq.end(),
     648                              it2 = rh->seq.begin(), it2end = rh->seq.end();
     649
     650        while (it1 != it1end && it2 != it2end) {
     651                int cmpval = compare(get_pointer(it1->bp), get_pointer(it2->bp));
     652                if (cmpval)
     653                        return cmpval;
     654                ++it1; ++it2;
     655        }
     656
     657        return (it1 == it1end) ? (it2 == it2end ? 0 : -1) : 1;
     658}
     659
     660// compare two function objects
     661// same behavior wihtin mul and add objects:
     662// we compare names
     663int ex_is_greater_degrevlex::compare_same_type_function(const function *lh,
     664                const function *rh) const
     665{
     666
     667        //std::cout<<"comparing names: "<<(lh->get_name() < rh->get_name())<<std::endl;
     668        /* Reversed ordering on char encoding (i.e. "a" < "b") then length (i.e. "abc" < "abcd")
     669           i.e. "x" > "y" and "xyz" > "xyzt" */
     670        if (lh->serial==rh->serial) //return 0;
     671                return compare_same_type_container(lh,rh);
     672        //std::cout<<"after if"<<std::endl;
     673        return lh->get_name() < rh->get_name() ? 1 : -1;       
     674
     675        //return lh->serial < rh->serial ? 1 : -1;
     676        //return -lh->compare_same_type(*rh);
     677}
     678
     679// compare two fderivative objects
     680// same behavior wihtin mul and add objects:
     681// we compare names
     682int ex_is_greater_degrevlex::compare_same_type_fderivative(const fderivative *lh,
     683                const fderivative *rh) const
     684{
     685        int cmpval = compare_same_type_function(lh, rh);
     686        if (cmpval != 0)
     687                return cmpval;
     688        if (lh->parameter_set != rh->parameter_set)
     689                return lh->parameter_set < rh->parameter_set ? -1 : 1;
     690        return 0;
    257691}
    258692
    259693} // namespace GiNaC
  • ginac/order.h

    diff -r a8d8d2018141 -r 67bdc3eefa16 ginac/order.h
    a b  
     1/** @file order.h
     2 *
     3 *  Definitions of order used for printing. */
     4
     5/*
     6 *  GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany
     7 *
     8 *  This program is free software; you can redistribute it and/or modify
     9 *  it under the terms of the GNU General Public License as published by
     10 *  the Free Software Foundation; either version 2 of the License, or
     11 *  (at your option) any later version.
     12 *
     13 *  This program is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 *  GNU General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU General Public License
     19 *  along with this program; if not, write to the Free Software
     20 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     21 */
     22
     23#ifndef __GINAC_ORDER_H__
     24#define __GINAC_ORDER_H__
     25
    126#include "ex.h"
    227#include "basic.h"
    328#include "mul.h"
    429#include "power.h"
    530#include "add.h"
    631#include "symbol.h"
     32#include "function.h"
     33#include "fderivative.h"
    734
    835namespace 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");
    1736
    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         };
     37struct ex_is_greater_degrevlex : public std::binary_function<ex, ex, bool> {
     38        const tinfo_t function_id;// = find_tinfo_key("function");
     39        const tinfo_t fderivative_id;// = find_tinfo_key("fderivative");
     40        const tinfo_t power_id;// = find_tinfo_key("power");
     41        const tinfo_t symbol_id;// = find_tinfo_key("symbol");
     42        const tinfo_t mul_id;// = find_tinfo_key("mul");
     43        const tinfo_t add_id;// = find_tinfo_key("add");
     44        const tinfo_t numeric_id;// = find_tinfo_key("numeric");
     45        const tinfo_t constant_id;// = find_tinfo_key("constant");
     46        const tinfo_t in_type_id;
    3547
    36 struct 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); }
     48        ex_is_greater_degrevlex(const tinfo_t type_id):
     49                function_id(find_tinfo_key("function")),
     50                fderivative_id(find_tinfo_key("fderivative")),
     51                power_id(find_tinfo_key("power")),
     52                symbol_id(find_tinfo_key("symbol")),
     53                mul_id(find_tinfo_key("mul")),
     54                add_id(find_tinfo_key("add")),
     55                numeric_id(find_tinfo_key("numeric")),
     56                constant_id(find_tinfo_key("constant")),
     57                in_type_id(type_id) {};
     58
     59        bool operator() (const ex &lh, const ex &rh) const;
     60        int compare(const ex &lh, const ex &rh) const;
     61        int compare(const basic *lh, const basic *rh) const;
     62        // mul objects
     63        int compare_mul_symbol(const mul *lh, const symbol *rh) const;
     64        int compare_mul_power(const mul *lh, const power *rh) const;
     65        int compare_same_type_mul(const mul *lh, const mul *rh) const;
     66        // add objects
     67        int compare_add_symbol(const add *lh, const symbol *rh) const;
     68        int compare_add_power(const add *lh, const power *rh) const;
     69        int compare_add_mul(const add *lh, const mul *rh) const;
     70        int compare_same_type_add(const add *lh, const add *rh) const;
     71        // power objects
     72        int compare_power_symbol(const power *lh, const symbol *rh) const;
     73        int compare_same_type_power(const power *lh, const power *rh) const;
     74        // symbol objects
     75        int compare_same_type_symbol(const symbol *lh, const symbol *rh) const;
     76        // container objects
     77        template <template <class T, class = std::allocator<T> > class C>
     78        int compare_same_type_container(const container<C> *lh,const container<C> *rh) const;
     79        // function objects
     80        int compare_same_type_function(const function *lh, const function *rh) const;
     81        // fderivative objects
     82        int compare_same_type_fderivative(const fderivative *lh, const fderivative *rh) const;
     83
     84        static const ex_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
     85          static ex_is_greater_degrevlex in_type[2] = {ex_is_greater_degrevlex(&add::tinfo_static),
     86                                                       ex_is_greater_degrevlex(&mul::tinfo_static)};
     87                if (in_type_id == &mul::tinfo_static)
     88                        return in_type[1];
     89                return in_type[0];
     90        }
    3891};
    3992
    40 }
     93// We have to define the following class to sort held expressions
     94// E.g. 3*x+2*x which does not get simplified to 5*x.
     95struct expair_is_greater_degrevlex : public std::binary_function<expair, expair, bool>
     96{
     97        const tinfo_t in_type_id;
     98        expair_is_greater_degrevlex(tinfo_t in_type):
     99                in_type_id(in_type) {};
     100        bool operator() (const expair &lh, const expair &rh) const;
     101
     102        static const expair_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
     103                static expair_is_greater_degrevlex in_type[2] = {expair_is_greater_degrevlex(&add::tinfo_static),expair_is_greater_degrevlex(&add::tinfo_static)};
     104                if (in_type_id == &mul::tinfo_static)
     105                        return in_type[1];
     106                return in_type[0];
     107        }
     108};
     109
     110struct expair_rest_is_greater_degrevlex : public std::binary_function<expair, expair, bool>
     111{
     112        const tinfo_t in_type_id;
     113        expair_rest_is_greater_degrevlex(tinfo_t in_type):
     114                in_type_id(in_type) {};
     115        bool operator() (const expair &lh, const expair &rh) const {
     116                return ex_is_greater_degrevlex::in_type(in_type_id)(lh.rest, rh.rest);
     117        }
     118
     119        static const expair_rest_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
     120                static expair_rest_is_greater_degrevlex in_type[2] = {expair_rest_is_greater_degrevlex(&add::tinfo_static),
     121                                        expair_rest_is_greater_degrevlex(&mul::tinfo_static)};
     122                if (in_type_id == &mul::tinfo_static)
     123                        return in_type[1];
     124                return in_type[0];
     125        }
     126};
     127
     128} // namespace GiNaC
     129
     130#endif // ndef __GINAC_ORDER_H__
  • ginac/order.cpp

    # HG changeset patch
    # User Jean-Pierre Flori <flori@enst.fr>
    # Date 1299164878 -3600
    # Node ID bc295f0e730a2ac8e3e11e063a9917aafe980582
    # Parent  67bdc3eefa160482ccbef431db334ee49159764f
    Further fixes.
    
    diff -r 67bdc3eefa16 -r bc295f0e730a ginac/order.cpp
    a b  
    314314                return cmpval;
    315315        }
    316316
     317        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     318                return 0;
     319
    317320        // there is something of total degree 0 in front of the mul object
    318321        return 1;
    319322}
     
    370373        // compare overall_coeff
    371374        cmpval = compare(get_pointer(lh->overall_coeff.bp),
    372375                        get_pointer(rh->overall_coeff.bp));
    373         if (cmpval!=0)
    374                 return cmpval;
    375376
    376         return 0;
     377        return cmpval;
    377378}
    378379
    379380// compare an add and a symbol objects
     
    401402                return cmpval;
    402403        }
    403404
    404         if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     405        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex0))
    405406                return 0;
    406407
    407408        // there is something at the end of the add object
     
    429430                return cmpval;
    430431        }
    431432
    432         if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     433        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex0))
    433434                return 0;
    434435
    435436        // there is something at the end of the object
     
    457458                return cmpval;
    458459        }
    459460
    460         if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     461        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex0))
    461462                return 0;
    462463
    463464        // there is something at the end of the object
     
    504505        // compare overall_coeff
    505506        cmpval = compare(get_pointer(lh->overall_coeff.bp),
    506507                        get_pointer(rh->overall_coeff.bp));
    507         if (cmpval!=0)
    508                 return cmpval;
    509 
    510         return 0;
     508       
     509        return cmpval;
    511510}
    512511
    513512// compare a power and a symbol objects
     
    530529                          return cmpval;
    531530               
    532531                cmpval = compare(get_pointer(lh->exponent.bp), _num1_p);
    533                 if (cmpval != 0)
    534                           return cmpval;
    535                 return 0;
     532               
     533                return cmpval;
    536534        }
    537535
    538536        // We are in an add object
     
    550548        }
    551549
    552550        cmpval = compare(get_pointer(lh->basis.bp), rh);
    553         if (cmpval != 0)
    554                 return cmpval;
    555        
    556         return 0;
     551
     552        return cmpval;
    557553}
    558554
    559555// compare two power objects
     
    573569                if (cmpval != 0)
    574570                          return cmpval;
    575571                cmpval = compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
    576                 if (cmpval != 0)
    577                           return cmpval;
    578                 return 0;
     572               
     573                return cmpval;
    579574        }
    580575
    581576        double lh_deg = 1;