Ticket #9880: trac9880-pynac_order_jp_new.patch

File trac9880-pynac_order_jp_new.patch, 29.4 KB (added by jpflori, 11 years ago)

Patch to apply on top of the other one

  • ginac/basic.h

    # HG changeset patch
    # User Jean-Pierre Flori <flori@enst.fr>
    # Date 1286807838 -7200
    # Node ID cbcd8b87203a347bc80de434afb177de143a3974
    # Parent  a8d8d201814186823ebc1204f5acf55e0b8b5b91
    imported patch further
    
    diff -r a8d8d2018141 -r cbcd8b87203a 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/ex.h

    diff -r a8d8d2018141 -r cbcd8b87203a 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 cbcd8b87203a 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 cbcd8b87203a ginac/expairseq.h
    a b  
    133133        void make_flat(const epvector & v, bool do_index_renaming = false);
    134134        void canonicalize();
    135135        void combine_same_terms_sorted_seq();
     136        epvector* get_sorted_seq() const;
    136137#if EXPAIRSEQ_USE_HASHTAB
    137138        void combine_same_terms();
    138139        unsigned calc_hashtabsize(unsigned sz) const;
     
    159160        std::auto_ptr<epvector> evalchildren(int level) const;
    160161        std::auto_ptr<epvector> subschildren(const exmap & m, unsigned options = 0) const;
    161162       
    162         epvector* get_sorted_seq() const;
    163163// member variables
    164164       
    165165protected:
  • ginac/fderivative.h

    diff -r a8d8d2018141 -r cbcd8b87203a 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 cbcd8b87203a 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 cbcd8b87203a ginac/mul.cpp
    a b  
    11871187        return (new add(addseq))->setflag(status_flags::dynallocated);
    11881188}
    11891189
     1190/** Total degree of a mul object.
     1191 Beware that symbolic exponents are wrapped inside pow objects with 1 as coeff. */
    11901192double mul::total_degree() const
    11911193{
    11921194        if (flags & status_flags::tdegree_calculated) {
  • ginac/mul.h

    diff -r a8d8d2018141 -r cbcd8b87203a 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;
  • ginac/order.cpp

    diff -r a8d8d2018141 -r cbcd8b87203a 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 {
    1344        //std::cout<<"in ex_is_greater_degrevlex::operator()"<<std::endl;
    1445        //std::cout<<"lh: ";
     
    2152        return compare(lh, rh) == 1;
    2253}
    2354
     55bool expair_is_greater_degrevlex::operator() (const expair &lhex, const expair &rhex) const
     56{
     57        const basic *lh = get_pointer(lhex.rest.bp);
     58        const basic *rh = get_pointer(rhex.rest.bp);
     59
     60        // compare rests
     61        int cmpval = ex_is_greater_degrevlex::in_type(in_type_id).compare(lh, rh);
     62        if (cmpval != 0) {
     63                return cmpval == 1;
     64        }
     65
     66        // compare coeffs which are numerics
     67        //std::cout << "comparing coeffs" << std::endl;
     68        //lhex.coeff.bp->dbgprinttree();
     69        //rhex.coeff.bp->dbgprinttree();
     70        numeric lh_coeff = ex_to<numeric>(lhex.coeff);
     71        numeric rh_coeff = ex_to<numeric>(rhex.coeff);
     72        // strange...
     73        //std::cout<<lh->compare_same_type(rh)<<std::endl;
     74        //return lh->compare_same_type(rh) == 1;
     75        double lh_deg = 1;
     76        double rh_deg = 1;
     77                if (lh_coeff.is_real()) {
     78                        lh_deg = lh_coeff.to_double();
     79                } else {
     80                        lh_deg = std::sqrt(std::pow(lh_coeff.real().to_double(), 2) +
     81                                        std::pow(lh_coeff.imag().to_double(), 2));
     82                }
     83                if (rh_coeff.is_real()) {
     84                        rh_deg = rh_coeff.to_double();
     85                } else {
     86                        rh_deg = std::sqrt(std::pow(rh_coeff.real().to_double(), 2) +
     87                                        std::pow(rh_coeff.imag().to_double(), 2));
     88                }
     89
     90        return lh_deg > rh_deg;
     91       
     92}
     93
     94/** Comparison functions:
     95 They should implement 'degrevlex' of SAGE
     96 i.e. graded reversed lexicographic order
     97 The lexicographic order should depend on the "creation" order of variables ?
     98 Or should it be a "natural" one on strings : a > b > ... > x > y > ... ?
     99*/
     100
     101/** Return values for comparison functions :
     102 compare(a,b) should return :
     103 -1 if a < b
     104 0 if a == b
     105 1 if a > b
     106 as <=> in Perl and GiNaC internal functions
     107*/
     108
    24109int ex_is_greater_degrevlex::compare(const basic *lh, const basic *rh) const {
    25110        const tinfo_t typeid_lh = lh->tinfo();
    26111        const tinfo_t typeid_rh = rh->tinfo();
     
    42127                        return compare_same_type_power(
    43128                                        static_cast<const power*>(lh),
    44129                                        static_cast<const power*>(rh));
     130                } else if (typeid_rh == function_id) {
     131                        return compare_same_type_function(
     132                                        static_cast<const function*>(lh),
     133                                        static_cast<const function*>(rh));
     134                } else if (typeid_rh == fderivative_id) {
     135                        return compare_same_type_fderivative(
     136                                        static_cast<const fderivative*>(lh),
     137                                        static_cast<const fderivative*>(rh));
    45138                } else {
     139                        // using GiNaC functions by default
    46140                        return lh->compare_same_type(*rh);
    47141                }
     142        // at present numerics are combined into overall_coefficient
     143        // even when hold parameter is used
     144        } else if (typeid_lh == numeric_id) {
     145                //print numerics after anything else
     146                return -1;
     147        } else if (typeid_rh == numeric_id) {
     148                //print numerics after anything else
     149                return 1;
    48150        } else if (typeid_lh == fderivative_id) {
    49                 //print fderivatives after everything
     151                //print fderivatives after everything else
    50152                return -1;
     153        } else if (typeid_rh == fderivative_id) {
     154                //print fderivatives after everything esle
     155                return 1;
    51156        } else if (typeid_lh == function_id) {
    52157                //print functions before fderivatives, after anything else
    53                 return typeid_rh == fderivative_id ? 1 : -1;
     158                return -1;
     159        } else if (typeid_rh == function_id) {
     160                //print functions before fderivatives, after anything else
     161                return 1;
    54162        } else if (typeid_lh == mul_id) {
    55163                if (typeid_rh == power_id) {
    56164                        return compare_mul_power(
     
    61169                                        static_cast<const mul*>(lh),
    62170                                        static_cast<const symbol*>(rh));
    63171                }
     172        } else if (typeid_lh == add_id) {
     173                if (typeid_rh == power_id) {
     174                        return compare_add_power(
     175                                        static_cast<const add*>(lh),
     176                                        static_cast<const power*>(rh));
     177                } else if (typeid_rh == symbol_id) {
     178                        return compare_add_symbol(
     179                                        static_cast<const add*>(lh),
     180                                        static_cast<const symbol*>(rh));
     181                }
    64182        } else if (typeid_lh == power_id) {
    65183                if (typeid_rh == mul_id) {
    66184                        return -compare_mul_power(
    67185                                        static_cast<const mul*>(rh),
    68186                                        static_cast<const power*>(lh));
     187                } else if (typeid_rh == add_id) {
     188                        return -compare_add_power(
     189                                        static_cast<const add*>(rh),
     190                                        static_cast<const power*>(lh));
    69191                } else if (typeid_rh == symbol_id) {
    70192                        return compare_power_symbol(
    71193                                        static_cast<const power*>(lh),
     
    76198                        return -compare_mul_symbol(
    77199                                        static_cast<const mul*>(rh),
    78200                                        static_cast<const symbol*>(lh));
     201                } else if (typeid_rh == add_id) {
     202                        return -compare_add_symbol(
     203                                        static_cast<const add*>(rh),
     204                                        static_cast<const symbol*>(lh));
    79205                } else if (typeid_rh == power_id) {
    80206                        return -compare_power_symbol(
    81207                                        static_cast<const power*>(rh),
     
    83209                }
    84210        }
    85211        //std::cout<<"comparing typeid's"<<std::endl;
    86         return (typeid_lh<typeid_rh ? 1 : -1);
     212        return (typeid_lh<typeid_rh ? -1 : 1);
    87213}
    88214
     215// compare a mul and a symbol objects
     216// same behavior within mul and add objects:
     217// the total degree of the symbol is 1
     218// check total degree of mul then compare smallest item to symbol
    89219int ex_is_greater_degrevlex::compare_mul_symbol(const mul *lh,
    90220                const symbol *rh) const
    91221{
    92222        int cmpval;
     223
    93224        double tdeg;
    94225        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;
     226
     227        if (tdeg != 1)
     228                return tdeg > 1 ? 1 : -1;
     229       
     230        const expair smallest_item = lh->get_sorted_seq()->back();
     231
     232        // compare bases
     233        cmpval = compare(get_pointer(smallest_item.rest.bp), rh);
     234        if (cmpval != 0) {
     235                return cmpval;
    106236        }
    107         return tdeg > 1 ? 1 : -1;
     237
     238        // compare exponents
     239        cmpval = -compare(get_pointer(smallest_item.coeff.bp),_num1_p);
     240        if (cmpval != 0) {
     241                return cmpval;
     242        }
     243
     244        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     245                return 0;
     246
     247        // there is something of total degree 0 in front of the mul object
     248        return 1;
    108249}
    109250
    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
     251
     252// compare a mul and a pow objects
     253// same behavior wihtin mul and add objects:
     254// first we compare total degrees
     255// if equal we compare the smallest basis in the sequence to the basis in other
     256// then their exponents
    113257int ex_is_greater_degrevlex::compare_mul_power(const mul *lh,
    114258                const power *rh) const
    115259{
     260        int cmpval;
     261
    116262        double lh_deg = lh->total_degree();
    117         double rh_deg;
     263        double rh_deg = 1;
    118264        numeric rh_exp;
    119         int cmpval = 0;
    120265        if (is_a<numeric>(rh->exponent)) {
    121266                rh_exp = ex_to<numeric>(rh->exponent);
    122267                if (rh_exp.is_real()) {
     
    125270                        rh_deg = std::sqrt(std::pow(rh_exp.real().to_double(), 2) +
    126271                                        std::pow(rh_exp.imag().to_double(), 2));
    127272                }
    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;
    135273        }
    136         cmpval = compare(get_pointer(lh->seq[0].rest.bp),
     274        if (rh_deg != lh_deg)
     275                return lh_deg < rh_deg ? -1 : 1;
     276        // same total degree
     277
     278        // smallest item is at the end of the sorted sequence
     279        const expair smallest_item = lh->get_sorted_seq()->back();
     280       
     281        // compare bases
     282        cmpval = compare(get_pointer(smallest_item.rest.bp),
    137283                        get_pointer(rh->basis.bp));
    138284        if (cmpval != 0) {
    139285                return cmpval;
    140286        }
    141         if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
    142                 return 0;
     287
     288        // compare exponents
     289        cmpval = -compare(get_pointer(smallest_item.coeff.bp),
     290                        get_pointer(rh->exponent.bp));
     291        if (cmpval != 0) {
     292                return cmpval;
     293        }
     294
     295        // there is something of total degree 0 in front of the mul object
    143296        return 1;
    144297}
    145298
     299// compare two mul objects
     300// same behavior wihtin mul and add objects:
     301// first we compare total degrees
     302// if equal we compare the smallest basis in the sequence to the basis in other
     303// then their exponents
    146304int ex_is_greater_degrevlex::compare_same_type_mul(const mul *lh,
    147305                const mul *rh) const
    148306{
     
    153311        double rh_deg = rh->total_degree();
    154312        if (lh_deg != rh_deg)
    155313                return lh_deg < rh_deg ? -1 : 1;
    156 
     314       
    157315        // 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();
     316        const epvector *sorted_seq1 = lh->get_sorted_seq();
     317        const epvector *sorted_seq2 = rh->get_sorted_seq();
     318        epvector::const_reverse_iterator cit1 = sorted_seq1->rbegin();
     319        epvector::const_reverse_iterator cit2 = sorted_seq2->rbegin();
     320        epvector::const_reverse_iterator last1 = sorted_seq1->rend();
     321        epvector::const_reverse_iterator last2 = sorted_seq2->rend();
    162322
    163323        for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
    164                 cmpval = ( cit1->compare(*cit2));
    165                 if (cmpval != 0)
     324                // compare bases
     325                cmpval = compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
     326                if (cmpval != 0) {
    166327                        return cmpval;
     328                }
     329
     330                // compare exponents
     331                cmpval = -compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
     332                if (cmpval != 0) {
     333                        return cmpval;
     334                }
    167335        }
    168336
    169337        // compare sizes
     
    181349        return 0;
    182350}
    183351
     352// compare an add and a symbol objects
     353// same behavior wihtin mul and add objects:
     354// the total degree of the symbol is 1
     355int ex_is_greater_degrevlex::compare_add_symbol(const add *lh,
     356                const symbol *rh) const
     357{
     358        int cmpval;
     359        const expair biggest_item = lh->get_sorted_seq()->front();
     360
     361        // compare bases
     362        cmpval = compare(get_pointer(biggest_item.rest.bp), rh);
     363        if (cmpval != 0) {
     364                return cmpval;
     365        }
     366
     367        // compare coefficients
     368        cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
     369        if (cmpval != 0) {
     370                return cmpval;
     371        }
     372
     373        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     374                return 0;
     375
     376        // there is something at the end of the add object
     377        return 1;
     378}
     379
     380
     381// compare an add and a pow objects
     382// same behavior wihtin mul and add objects:
     383int ex_is_greater_degrevlex::compare_add_power(const add *lh,
     384                const power *rh) const
     385{
     386        int cmpval;
     387        const expair biggest_item = lh->get_sorted_seq()->front();
     388
     389        // compare bases
     390        cmpval = compare(get_pointer(biggest_item.rest.bp), rh);
     391        if (cmpval != 0) {
     392                return cmpval;
     393        }
     394
     395        // compare coefficients
     396        cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
     397        if (cmpval != 0) {
     398                return cmpval;
     399        }
     400
     401        if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
     402                return 0;
     403
     404        // there is something at the end of the object
     405        return 1;
     406}
     407
     408// compare two add objects
     409// same behavior wihtin mul and add objects:
     410// first we compare the total degrees of the biggest items
     411// then their exponents
     412// then their bases
    184413int ex_is_greater_degrevlex::compare_same_type_add(const add *lh,
    185414                const add *rh) const
    186415{
    187416        int cmpval;
    188417
    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();
     418        const epvector *sorted_seq1 = lh->get_sorted_seq();
     419        const epvector *sorted_seq2 = rh->get_sorted_seq();
     420        epvector::const_iterator cit1 = sorted_seq1->begin();
     421        epvector::const_iterator cit2 = sorted_seq2->begin();
     422        epvector::const_iterator last1 = sorted_seq1->end();
     423        epvector::const_iterator last2 = sorted_seq2->end();
    197424
    198425        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;
     426                // compare bases
     427                cmpval = compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
     428                if (cmpval != 0) {
     429                        return cmpval;
     430                }
     431
     432                // compare coefficients
     433                cmpval = compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
     434                if (cmpval != 0) {
     435                        return cmpval;
     436                }
    202437        }
    203438
    204         GINAC_ASSERT(cit1==last1);
    205         GINAC_ASSERT(cit2==last2);
     439        // compare sizes
     440        if (cit1 != last1)
     441                return 1;
     442        else if (cit2 != last2)
     443                return -1;
    206444
    207445        // compare overall_coeff
    208446        cmpval = compare(get_pointer(lh->overall_coeff.bp),
     
    213451        return 0;
    214452}
    215453
     454// compare a power and a symbol objects
     455// does not behave the same way inside add or mul
     456// in mul object:
     457// fist we compare bases
     458// then exponents
     459// in add object:
     460// first exponents
     461// then bases
    216462int ex_is_greater_degrevlex::compare_power_symbol(const power *lh,
    217463                const symbol *rh) const
    218464{
     465        int cmpval;
     466
    219467        //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;
     468        if (in_type_id == &mul::tinfo_static) {
     469                cmpval = compare(get_pointer(lh->basis.bp), rh);
     470                if (cmpval != 0)
     471                          return cmpval;
     472               
     473                cmpval = compare(get_pointer(lh->exponent.bp), _num1_p);
     474                if (cmpval != 0)
     475                          return cmpval;
     476                return 0;
    224477        }
    225         return compare(get_pointer(lh->basis.bp), rh);
     478 
     479        if (is_a<numeric>(lh->exponent)) {
     480                numeric lh_exp = ex_to<numeric>(lh->exponent);
     481                double lh_deg;
     482                if (lh_exp.is_real()) {
     483                        lh_deg = lh_exp.to_double();
     484                } else {
     485                        lh_deg = std::sqrt(std::pow(lh_exp.real().to_double(), 2) +
     486                                        std::pow(lh_exp.imag().to_double(), 2));
     487                }
     488                if (lh_deg != 1)
     489                        return lh_deg < 1 ? -1 : 1;
     490        }
     491
     492        cmpval = compare(get_pointer(lh->basis.bp), rh);
     493        if (cmpval != 0)
     494                return cmpval;
     495       
     496        return 1;
    226497}
    227498
     499// compare two power objects
     500// does not behave the same way inside add or mul
     501// in mul object:
     502// fist we compare bases
     503// then exponents
     504// in add object:
     505// first exponents
     506// then bases
    228507int ex_is_greater_degrevlex::compare_same_type_power(const power *lh,
    229                 const power *rh) const
     508                const power *rh) const
    230509{
    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));
     510        int cmpval;
     511        if (in_type_id == &mul::tinfo_static) {
     512                cmpval = compare(get_pointer(lh->basis.bp), get_pointer(rh->basis.bp));
     513                if (cmpval != 0)
     514                          return cmpval;
     515                cmpval = compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
     516                if (cmpval != 0)
     517                          return cmpval;
     518                return 0;
     519        }
     520
     521        double lh_deg = 1;
     522        double rh_deg = 1;
     523        if (is_a<numeric>(lh->exponent)) {
     524                numeric lh_exp = ex_to<numeric>(lh->exponent);
     525                if (lh_exp.is_real()) {
     526                        lh_deg = lh_exp.to_double();
     527                } else {
     528                        lh_deg = std::sqrt(std::pow(lh_exp.real().to_double(), 2) +
     529                                        std::pow(lh_exp.imag().to_double(), 2));
     530                }
     531        }
     532        if (is_a<numeric>(rh->exponent)) {
     533                numeric rh_exp = ex_to<numeric>(rh->exponent);
     534                if (rh_exp.is_real()) {
     535                        rh_deg = rh_exp.to_double();
     536                } else {
     537                        rh_deg = std::sqrt(std::pow(rh_exp.real().to_double(), 2) +
     538                                        std::pow(rh_exp.imag().to_double(), 2));
     539                }
     540        }
     541        if (rh_deg != lh_deg)
     542                return lh_deg < rh_deg ? -1 : 1;
     543
     544        cmpval = compare(get_pointer(lh->basis.bp),
     545                         get_pointer(rh->basis.bp));
     546        if (cmpval != 0)
     547                return cmpval;
     548
     549        if (is_a<numeric>(lh->exponent) && is_a<numeric>(rh->exponent))
     550                return 0;
     551        return compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
    238552}
    239553
     554// compare two symbol objects
     555// same behavior wihtin mul and add objects:
     556// we compare names
    240557int ex_is_greater_degrevlex::compare_same_type_symbol(const symbol *lh,
    241558                const symbol *rh) const
    242559{
     
    246563        //std::cout<<"rh: ";
    247564        //rh->dbgprint();
    248565        //std::cout<<std::endl;
     566
     567        // Weird because Sage sorts based on creation order.
     568        // SAGE/Pynac: Sorting based on creation order doesn't work for Sage.
     569        // instead we sort on variable name. -- William Stein
     570
     571        //std::cout<<"comparing names: "<<(lh->name < rh->name)<<std::endl;
     572        /* Reversed ordering on char encoding (i.e. "a" < "b") then length (i.e. "abc" < "abcd")
     573           i.e. "x" > "y" and "xyz" > "xyzt" */
    249574        if (lh->serial==rh->serial) return 0;
    250575        //std::cout<<"after if"<<std::endl;
     576        return lh->name < rh->name ? 1 : -1;
    251577
    252 // SAGE/Pynac: Sorting based on creation order doesn't work for Sage.
    253 // instead we sort on variable name. -- William Stein
     578        //return lh->serial < rh->serial ? 1 : -1;
     579        //return -lh->compare_same_type(*rh);
     580}
    254581
    255         //std::cout<<"comparing names: "<<(lh->name < rh->name)<<std::endl;
    256         return lh->name < (rh->name) ? 1 : -1;
     582// compare two function objects
     583// same behavior wihtin mul and add objects:
     584// we compare names
     585int ex_is_greater_degrevlex::compare_same_type_function(const function *lh,
     586                const function *rh) const
     587{
     588
     589        //std::cout<<"comparing names: "<<(lh->get_name() < rh->get_name())<<std::endl;
     590        /* Reversed ordering on char encoding (i.e. "a" < "b") then length (i.e. "abc" < "abcd")
     591           i.e. "x" > "y" and "xyz" > "xyzt" */
     592        if (lh->serial==rh->serial) return 0;
     593        //std::cout<<"after if"<<std::endl;
     594        return lh->get_name() < rh->get_name() ? 1 : -1;
     595
     596        //return lh->serial < rh->serial ? 1 : -1;
     597        //return -lh->compare_same_type(*rh);
     598}
     599
     600// compare two fderivative objects
     601// same behavior wihtin mul and add objects:
     602// we compare names
     603int ex_is_greater_degrevlex::compare_same_type_fderivative(const fderivative *lh,
     604                const fderivative *rh) const
     605{
     606
     607        //std::cout<<"comparing names: "<<(lh->get_name() < rh->get_name())<<std::endl;
     608        /* Reversed ordering on char encoding (i.e. "a" < "b") then length (i.e. "abc" < "abcd")
     609           i.e. "x" > "y" and "xyz" > "xyzt" */
     610        if (lh->serial==rh->serial) return 0;
     611        //std::cout<<"after if"<<std::endl;
     612        return lh->get_name() < rh->get_name() ? 1 : -1;
     613
     614        //return lh->serial < rh->serial ? 1 : -1;
     615        //return -lh->compare_same_type(*rh);
    257616}
    258617
    259618} // namespace GiNaC
  • ginac/order.h

    diff -r a8d8d2018141 -r cbcd8b87203a 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 in_type_id;
    3546
    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); }
     47        ex_is_greater_degrevlex(const tinfo_t type_id):
     48                function_id(find_tinfo_key("function")),
     49                fderivative_id(find_tinfo_key("fderivative")),
     50                power_id(find_tinfo_key("power")),
     51                symbol_id(find_tinfo_key("symbol")),
     52                mul_id(find_tinfo_key("mul")),
     53                add_id(find_tinfo_key("add")),
     54                numeric_id(find_tinfo_key("numeric")),
     55                in_type_id(type_id) {};
     56
     57        bool operator() (const ex &lh, const ex &rh) const;
     58        //int compare(const ex &lh, const ex &rh) const;
     59        int compare(const basic *lh, const basic *rh) const;
     60        // mul objects
     61        int compare_mul_symbol(const mul *lh, const symbol *rh) const;
     62        int compare_mul_power(const mul *lh, const power *rh) const;
     63        int compare_same_type_mul(const mul *lh, const mul *rh) const;
     64        // add objects
     65        int compare_add_symbol(const add *lh, const symbol *rh) const;
     66        int compare_add_power(const add *lh, const power *rh) const;
     67        int compare_same_type_add(const add *lh, const add *rh) const;
     68        // power objects
     69        int compare_power_symbol(const power *lh, const symbol *rh) const;
     70        int compare_same_type_power(const power *lh, const power *rh) const;
     71        // symbol objects
     72        int compare_same_type_symbol(const symbol *lh, const symbol *rh) const;
     73        // function objects
     74        int compare_same_type_function(const function *lh, const function *rh) const;
     75        // fderivative objects
     76        int compare_same_type_fderivative(const fderivative *lh, const fderivative *rh) const;
     77
     78        static const ex_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
     79          static ex_is_greater_degrevlex in_type[2] = {ex_is_greater_degrevlex(&add::tinfo_static),
     80                                                       ex_is_greater_degrevlex(&mul::tinfo_static)};
     81                if (in_type_id == &mul::tinfo_static)
     82                        return in_type[1];
     83                return in_type[0];
     84        }
    3885};
    3986
    40 }
     87// We have to define the following class to sort held expressions.
     88struct expair_is_greater_degrevlex : public std::binary_function<expair, expair, bool>
     89{
     90        const tinfo_t in_type_id;
     91        expair_is_greater_degrevlex(tinfo_t in_type):
     92                in_type_id(in_type) {};
     93        bool operator() (const expair &lh, const expair &rh) const;
     94
     95        static const expair_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
     96                static expair_is_greater_degrevlex in_type[2] = {expair_is_greater_degrevlex(&add::tinfo_static),expair_is_greater_degrevlex(&add::tinfo_static)};
     97                if (in_type_id == &mul::tinfo_static)
     98                        return in_type[1];
     99                return in_type[0];
     100        }
     101};
     102
     103struct expair_rest_is_greater_degrevlex : public std::binary_function<expair, expair, bool>
     104{
     105        const tinfo_t in_type_id;
     106        expair_rest_is_greater_degrevlex(tinfo_t in_type):
     107                in_type_id(in_type) {};
     108        bool operator() (const expair &lh, const expair &rh) const {
     109                return ex_is_greater_degrevlex::in_type(in_type_id)(lh.rest, rh.rest);
     110        }
     111
     112        static const expair_rest_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
     113                static expair_rest_is_greater_degrevlex in_type[2] = {expair_rest_is_greater_degrevlex(&add::tinfo_static),
     114                                        expair_rest_is_greater_degrevlex(&mul::tinfo_static)};
     115                if (in_type_id == &mul::tinfo_static)
     116                        return in_type[1];
     117                return in_type[0];
     118        }
     119};
     120
     121} // namespace GiNaC
     122
     123#endif // ndef __GINAC_ORDER_H__