Source

pynac-patches / trac_9880-cleanup.patch

Full commit
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
# HG changeset patch
# Parent 3da59f712e0232e109b89c5eb0855109ddd96e5e
Clean up new order functions. Rename to print_order_*.
Make numerics and constants print first again, as in sqrt(2)*x.

diff --git a/ginac/add.cpp b/ginac/add.cpp
--- a/ginac/add.cpp
+++ b/ginac/add.cpp
@@ -31,6 +31,7 @@
 #include "constant.h"
 #include "infinity.h"
 #include "compiler.h"
+#include "order.h"
 
 #include <sstream>
 #include <iostream>
@@ -696,4 +697,15 @@
 	return (new add(vp, overall_coeff))->setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
 }
 
+epvector* add::get_sorted_seq() const
+{
+	if (!this->seq_sorted) {
+		seq_sorted = new epvector(seq.size());
+		partial_sort_copy(seq.begin(), seq.end(),
+				seq_sorted->begin(), seq_sorted->end(),
+				print_order_pair());
+	}
+	return seq_sorted;
+}
+
 } // namespace GiNaC
diff --git a/ginac/add.h b/ginac/add.h
--- a/ginac/add.h
+++ b/ginac/add.h
@@ -63,6 +63,7 @@
 	ex imag_part() const;
 	exvector get_free_indices() const;
 	ex eval_ncmul(const exvector & v) const;
+	epvector* get_sorted_seq() const;
 protected:
 	ex derivative(const symbol & s) const;
 	unsigned return_type() const;
diff --git a/ginac/basic.h b/ginac/basic.h
--- a/ginac/basic.h
+++ b/ginac/basic.h
@@ -108,8 +108,8 @@
 	GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(basic, void)
 	
 	friend class ex;
-	friend struct ex_is_greater_degrevlex;
-	friend struct expair_is_greater_degrevlex;
+	friend struct print_order;
+	friend struct print_order_pair;
 	// default constructor, destructor, copy constructor and assignment operator
 protected:
 	basic() : tinfo_key(&tinfo_static), flags(0) {}
diff --git a/ginac/container.h b/ginac/container.h
--- a/ginac/container.h
+++ b/ginac/container.h
@@ -129,7 +129,7 @@
 class container : public basic, public container_storage<C> {
 	GINAC_DECLARE_REGISTERED_CLASS(container, basic)
 
-	friend struct ex_is_greater_degrevlex;
+	friend struct print_order;
 
 protected:
 	typedef typename container_storage<C>::STLT STLT;
diff --git a/ginac/ex.h b/ginac/ex.h
--- a/ginac/ex.h
+++ b/ginac/ex.h
@@ -83,8 +83,9 @@
 	template<class T> friend inline bool is_a(const ex &);
 	template<class T> friend inline bool is_exactly_a(const ex &);
 	
-	friend struct ex_is_greater_degrevlex;
-	friend struct expair_is_greater_degrevlex;
+	friend struct print_order;
+	friend struct print_order_mul;
+	friend struct print_order_pair;
 	// default constructor, copy constructor and assignment operator
 public:
 	ex() throw();
diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp
--- a/ginac/expairseq.cpp
+++ b/ginac/expairseq.cpp
@@ -33,7 +33,6 @@
 #include "indexed.h"
 #include "infinity.h"
 #include "compiler.h"
-#include "order.h"
 
 #include <iostream>
 #include <algorithm>
@@ -1187,17 +1186,6 @@
 	std::sort(seq.begin(), seq.end(), expair_rest_is_less());
 }
 
-epvector* expairseq::get_sorted_seq() const
-{
-	if (!this->seq_sorted) {
-		seq_sorted = new epvector(seq.size());
-		partial_sort_copy(seq.begin(), seq.end(),
-				seq_sorted->begin(), seq_sorted->end(),
-				  expair_is_greater_degrevlex::in_type(tinfo()));
-	}
-	return seq_sorted;
-}
-
 
 /** Compact a presorted expairseq by combining all matching expairs to one
  *  each.  On an add object, this is responsible for 2*x+3*x+y -> 5*x+y, for
diff --git a/ginac/expairseq.h b/ginac/expairseq.h
--- a/ginac/expairseq.h
+++ b/ginac/expairseq.h
@@ -68,13 +68,14 @@
 {
 	GINAC_DECLARE_REGISTERED_CLASS(expairseq, basic)
 
-	friend struct ex_is_greater_degrevlex;
+	friend struct print_order;
 	// other constructors
 public:
 	expairseq(const ex & lh, const ex & rh);
 	expairseq(const exvector & v);
 	expairseq(const epvector & v, const ex & oc, bool do_index_renaming = false);
 	expairseq(std::auto_ptr<epvector>, const ex & oc, bool do_index_renaming = false);
+	~expairseq() { if (!seq_sorted) delete seq_sorted; }
 	
 	// functions overriding virtual functions from base classes
 public:
@@ -133,7 +134,6 @@
 	void make_flat(const epvector & v, bool do_index_renaming = false);
 	void canonicalize();
 	void combine_same_terms_sorted_seq();
-	epvector* get_sorted_seq() const;
 #if EXPAIRSEQ_USE_HASHTAB
 	void combine_same_terms();
 	unsigned calc_hashtabsize(unsigned sz) const;
diff --git a/ginac/fderivative.h b/ginac/fderivative.h
--- a/ginac/fderivative.h
+++ b/ginac/fderivative.h
@@ -40,7 +40,7 @@
 {
 	GINAC_DECLARE_REGISTERED_CLASS(fderivative, function)
 
-	friend struct ex_is_greater_degrevlex;
+	friend struct print_order;
 	// other constructors
 public:
 	/** Construct derivative with respect to one parameter.
diff --git a/ginac/function.h b/ginac/function.h
--- a/ginac/function.h
+++ b/ginac/function.h
@@ -310,7 +310,7 @@
 {
 	GINAC_DECLARE_REGISTERED_CLASS(function, exprseq)
 
-	friend struct ex_is_greater_degrevlex;
+	friend struct print_order;
 	// CINT has a linking problem
 #ifndef __MAKECINT__
 	friend void ginsh_get_ginac_functions();
diff --git a/ginac/mul.cpp b/ginac/mul.cpp
--- a/ginac/mul.cpp
+++ b/ginac/mul.cpp
@@ -1517,6 +1517,17 @@
 	}
 }
 
+epvector* mul::get_sorted_seq() const
+{
+	if (!this->seq_sorted) {
+		seq_sorted = new epvector(seq.size());
+		partial_sort_copy(seq.begin(), seq.end(),
+				seq_sorted->begin(), seq_sorted->end(),
+				print_order_pair_mul());
+	}
+	return seq_sorted;
+}
+
   
 //////////
 // new virtual functions which can be overridden by derived classes
diff --git a/ginac/mul.h b/ginac/mul.h
--- a/ginac/mul.h
+++ b/ginac/mul.h
@@ -33,7 +33,7 @@
 {
 	GINAC_DECLARE_REGISTERED_CLASS(mul, expairseq)
 	
-	friend struct ex_is_greater_degrevlex;
+	friend struct print_order;
 	friend class add;
 	friend class ncmul;
 	friend class power;
@@ -98,6 +98,7 @@
 public:
 	ex algebraic_subs_mul(const exmap & m, unsigned options) const;
 	double total_degree() const;
+	epvector* get_sorted_seq() const;
 	//int compare_symbol(const symbol &other) const;
 	//int compare_pow(const power &other) const;
 protected:
diff --git a/ginac/numeric.h b/ginac/numeric.h
--- a/ginac/numeric.h
+++ b/ginac/numeric.h
@@ -208,7 +208,6 @@
   class numeric : public basic
   {
     GINAC_DECLARE_REGISTERED_CLASS(numeric, basic)
-    //friend struct expair_is_greater_degrevlex;
     // member functions
 	
     // other constructors
diff --git a/ginac/order.cpp b/ginac/order.cpp
--- a/ginac/order.cpp
+++ b/ginac/order.cpp
@@ -30,78 +30,75 @@
 
 namespace GiNaC {
 
-/** What SAGE does for printing:
- To print multivariate polynomials, SAGE uses "reversed" (bigger terms first) 'degrevlex' order
- i.e. "reversed" graded reversed lexicographic order, the lexicographic order is defined below.
- The variables are ordered according to their "creation" order
- i.e PR.<x,a,t> = PolynomialRing(QQ) gives x > a > t
- and x+t+a is printed x + a + t
+double numeric_to_double(const numeric& exp)
+{
+	if (exp.is_real())
+		return exp.to_double();
+	else 
+		return std::sqrt(std::pow(exp.real().to_double(), 2) + 
+				std::pow(exp.imag().to_double(), 2));
+}
+
+/** What Sage does for printing:
+ To print multivariate polynomials, SAGE uses "reversed" (bigger terms first)
+ 'degrevlex' order i.e. "reversed" graded reversed lexicographic order, the
+ lexicographic order is defined below.  The variables are ordered according to
+ their "creation" order i.e PR.<x,a,t> = PolynomialRing(QQ) gives x > a > t and
+ x+t+a is printed x + a + t
 */
 
-/** Returns true if lhex > rhex for 'degrevlex' of SAGE
+/** Returns true if lhex > rhex for 'degrevlex' of Sage
  i.e. graded reversed lexicographic order
 */
-bool ex_is_greater_degrevlex::operator() (const ex &lhex, const ex &rhex) const {
-        //std::cout<<"in ex_is_greater_degrevlex::operator()"<<std::endl;
-	//std::cout<<"lh: ";
-	//lhex.dbgprint();
-	//std::cout<<std::endl<<"rh: ";
-	//rhex.dbgprint();
-	//std::cout<<std::endl;
+bool print_order::operator() (const ex &lhex, const ex &rhex) const {
 	const basic *lh = get_pointer(lhex.bp);
 	const basic *rh = get_pointer(rhex.bp);
 	return compare(lh, rh) == 1;
 }
 
-int ex_is_greater_degrevlex::compare (const ex &lhex, const ex &rhex) const {
+int print_order::compare (const ex &lhex, const ex &rhex) const {
 	const basic *lh = get_pointer(lhex.bp);
 	const basic *rh = get_pointer(rhex.bp);
 	return compare(lh, rh);
 }
 
-bool expair_is_greater_degrevlex::operator() (const expair &lhex, const expair &rhex) const
+bool print_order_pair_mul::operator() (const expair &lhex, const expair &rhex) const
+{
+	int cmpval = print_order_mul().compare(lhex.rest, rhex.rest);
+	if (cmpval != 0) {
+		return cmpval == 1;
+	}
+	return compare_degrees(lhex, rhex);
+}
+
+bool print_order_pair::operator() (const expair &lhex, const expair &rhex) const
 {
 	const basic *lh = get_pointer(lhex.rest.bp);
 	const basic *rh = get_pointer(rhex.rest.bp);
 
 	// compare rests
-        int cmpval = ex_is_greater_degrevlex::in_type(in_type_id).compare(lh, rh);
+	int cmpval = print_order().compare(lh, rh);
 	if (cmpval != 0) {
-	        return cmpval == 1;
+		return cmpval == 1;
 	}
+	return compare_degrees(lhex, rhex);
+}
 
+bool print_order_pair::compare_degrees(const expair &lhex,
+		const expair &rhex) const
+{
 	// compare coeffs which are numerics
-	//std::cout << "comparing coeffs" << std::endl;
-	//lhex.coeff.bp->dbgprinttree();
-	//rhex.coeff.bp->dbgprinttree();
-	numeric lh_coeff = ex_to<numeric>(lhex.coeff);
-	numeric rh_coeff = ex_to<numeric>(rhex.coeff);
-	// strange...
-	//std::cout<<lh->compare_same_type(rh)<<std::endl;
-	//return lh->compare_same_type(rh) == 1;
-	double lh_deg = 1;
-	double rh_deg = 1;
-		if (lh_coeff.is_real()) {
-			lh_deg = lh_coeff.to_double();
-		} else {
-			lh_deg = std::sqrt(std::pow(lh_coeff.real().to_double(), 2) + 
-					std::pow(lh_coeff.imag().to_double(), 2));
-		}
-		if (rh_coeff.is_real()) {
-			rh_deg = rh_coeff.to_double();
-		} else {
-			rh_deg = std::sqrt(std::pow(rh_coeff.real().to_double(), 2) + 
-					std::pow(rh_coeff.imag().to_double(), 2));
-		}
+	double lh_deg = numeric_to_double(ex_to<numeric>(lhex.coeff));
+	double rh_deg = numeric_to_double(ex_to<numeric>(rhex.coeff));
 
 	return lh_deg > rh_deg;	
 }
 
 /** Comparison functions:
- They should implement 'degrevlex' of SAGE
+ They should implement 'degrevlex' of Sage
  i.e. graded reversed lexicographic order
- The lexicographic order should depend on the "creation" order of variables ?
- Or should it be a "natural" one on strings : a > b > ... > x > y > ... ?
+ The lexicographic order is the "natural" one on strings:
+ a > b > ... > x > y > ... ?
 */
 
 /** Return values for comparison functions :
@@ -112,7 +109,7 @@
  as <=> in Perl and GiNaC internal functions
 */
 
-int ex_is_greater_degrevlex::compare(const basic *lh, const basic *rh) const {
+int print_order::compare(const basic *lh, const basic *rh) const {
 	const tinfo_t typeid_lh = lh->tinfo();
 	const tinfo_t typeid_rh = rh->tinfo();
 
@@ -142,23 +139,23 @@
 					static_cast<const fderivative*>(lh),
 					static_cast<const fderivative*>(rh));
 		} else {
-		        // using GiNaC functions by default
+			// using GiNaC functions by default
 			return lh->compare_same_type(*rh);
 		}
 	// at present numerics are combined into overall_coefficient
 	// even when hold parameter is used
 	} else if (typeid_lh == numeric_id) {
-	 	//print numerics after anything else
-	        return -1;
+	 	//print numerics before anything else
+		return 1;
 	} else if (typeid_rh == numeric_id) {
-	 	//print numerics after anything else
-	        return 1;
+	 	//print numerics before anything else
+		return -1;
 	} else if (typeid_lh == constant_id) {
-	 	//print constants after anything else
-	        return -1;
+	 	//print constants before anything else (but numerics)
+		return 1;
 	} else if (typeid_rh == constant_id) {
-	 	//print constants after anything else
-	        return 1;
+	 	//print constants before anything else (but numerics)
+		return -1;
 	} else if (typeid_lh == fderivative_id) {
 		//print fderivatives after everything else
 		return -1;
@@ -167,10 +164,10 @@
 		return 1;
 	} else if (typeid_lh == function_id) {
 		//print functions before fderivatives, after anything else
-	        return -1;
+		return -1;
 	} else if (typeid_rh == function_id) {
 		//print functions before fderivatives, after anything else
-	        return 1;
+		return 1;
 	} else if (typeid_lh == mul_id) {
 		if (typeid_rh == power_id) {
 			return compare_mul_power(
@@ -227,28 +224,24 @@
 					static_cast<const power*>(rh),
 					static_cast<const symbol*>(lh));
 		}
-        }
-	std::cout<<"comparing typeid's"<<std::endl;
-	return (typeid_lh<typeid_rh ? -1 : 1);
+	}
+	throw (std::runtime_error("comparing typeid's"));
 }
 
 // compare a mul and a symbol objects
 // same behavior within mul and add objects:
 // the total degree of the symbol is 1
 // check total degree of mul then compare smallest item to symbol
-int ex_is_greater_degrevlex::compare_mul_symbol(const mul *lh,
+int print_order::compare_mul_symbol(const mul *lh,
 		const symbol *rh) const
 {
-  //std::cout<<"comparing mul and symbol"<<std::endl;
-  //lh->dbgprint();
-  //rh->dbgprint();
 	int cmpval;
 
 	double tdeg;
 	tdeg = lh->total_degree();
 
 	if (tdeg != 1)
-	        return tdeg > 1 ? 1 : -1;
+		return tdeg > 1 ? 1 : -1;
 	
 	const expair smallest_item = lh->get_sorted_seq()->back();
 
@@ -271,13 +264,12 @@
 	return 1;
 }
 
-
 // compare a mul and a pow objects
-// same behavior wihtin mul and add objects:
+// same behavior within mul and add objects:
 // first we compare total degrees
 // if equal we compare the smallest basis in the sequence to the basis in other
 // then their exponents
-int ex_is_greater_degrevlex::compare_mul_power(const mul *lh,
+int print_order::compare_mul_power(const mul *lh,
 		const power *rh) const
 {
 	int cmpval;
@@ -286,13 +278,7 @@
 	double rh_deg = 1;
 	numeric rh_exp;
 	if (is_a<numeric>(rh->exponent)) {
-		rh_exp = ex_to<numeric>(rh->exponent);
-		if (rh_exp.is_real()) {
-			rh_deg = rh_exp.to_double();
-		} else {
-			rh_deg = std::sqrt(std::pow(rh_exp.real().to_double(), 2) + 
-					std::pow(rh_exp.imag().to_double(), 2));
-		}
+		rh_deg = numeric_to_double(ex_to<numeric>(rh->exponent));
 	}
 	if (rh_deg != lh_deg)
 		return lh_deg < rh_deg ? -1 : 1;
@@ -310,7 +296,7 @@
 
 	// compare exponents
 	cmpval = -compare(get_pointer(smallest_item.coeff.bp),
-		        get_pointer(rh->exponent.bp));
+			get_pointer(rh->exponent.bp));
 	if (cmpval != 0) {
 		return cmpval;
 	}
@@ -328,18 +314,14 @@
 // if equal we compare the basis of the smallest items
 // then their exponents
 // and so on
-int ex_is_greater_degrevlex::compare_same_type_mul(const mul *lh,
+int print_order::compare_same_type_mul(const mul *lh,
 		const mul *rh) const
 {
-  //std::cout<<"comparing mul and mul"<<std::endl;
-  //lh->dbgprint();
-  //rh->dbgprint();
 	int cmpval;
 	
 	// compare total degrees
 	double lh_deg = lh->total_degree();
 	double rh_deg = rh->total_degree();
-        //std::cout<<"degree "<<lh_deg<<" and "<<rh_deg<<std::endl;
 	if (lh_deg != rh_deg)
 		return lh_deg < rh_deg ? -1 : 1;
 	
@@ -353,13 +335,15 @@
 
 	for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
 		// compare bases
-		cmpval = compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
+		cmpval = compare(get_pointer(cit1->rest.bp),
+				get_pointer(cit2->rest.bp));
 		if (cmpval != 0) {
 			return cmpval;
 		}
 
 		// compare exponents
-	        cmpval = -compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
+		cmpval = -compare(get_pointer(cit1->coeff.bp),
+				get_pointer(cit2->coeff.bp));
 		if (cmpval != 0) {
 			return cmpval;
 		}
@@ -381,18 +365,15 @@
 // compare an add and a symbol objects
 // same behavior wihtin mul and add objects:
 // the coefficient of the symbol is 1
-int ex_is_greater_degrevlex::compare_add_symbol(const add *lh,
+int print_order::compare_add_symbol(const add *lh,
 		const symbol *rh) const
 {
-  //std::cout<<"comparing add and symbol"<<std::endl;
-  //lh->dbgprint();
-  //rh->dbgprint();
 	int cmpval;
 
 	const expair biggest_item = lh->get_sorted_seq()->front();
 
 	// compare bases
-	cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(biggest_item.rest.bp), rh);
+	cmpval = print_order().compare(get_pointer(biggest_item.rest.bp), rh);
 	if (cmpval != 0) {
 		return cmpval;
 	}
@@ -413,14 +394,14 @@
 // compare an add and a mul objects
 // same behavior within mul and add objects:
 // the coefficient of the mul object is 1
-int ex_is_greater_degrevlex::compare_add_mul(const add *lh,
+int print_order::compare_add_mul(const add *lh,
 		const mul *rh) const
 {
-        int cmpval;
+	int cmpval;
 	const expair biggest_item = lh->get_sorted_seq()->front();
 
 	// compare bases
-	cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(biggest_item.rest.bp), rh);
+	cmpval = print_order().compare(get_pointer(biggest_item.rest.bp), rh);
 	if (cmpval != 0) {
 		return cmpval;
 	}
@@ -441,14 +422,14 @@
 // compare an add and a pow objects
 // same behavior wihtin mul and add objects:
 // the coefficient of the power object is 1
-int ex_is_greater_degrevlex::compare_add_power(const add *lh,
+int print_order::compare_add_power(const add *lh,
 		const power *rh) const
 {
-        int cmpval;
+	int cmpval;
 	const expair biggest_item = lh->get_sorted_seq()->front();
 
 	// compare bases
-	cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(biggest_item.rest.bp), rh);
+	cmpval = print_order().compare(get_pointer(biggest_item.rest.bp), rh);
 	if (cmpval != 0) {
 		return cmpval;
 	}
@@ -471,7 +452,7 @@
 // first we compare the basis of the biggest items
 // then their coefficients
 // and so on
-int ex_is_greater_degrevlex::compare_same_type_add(const add *lh,
+int print_order::compare_same_type_add(const add *lh,
 		const add *rh) const
 {
 	int cmpval;
@@ -485,13 +466,13 @@
 
 	for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
 		// compare bases
-		cmpval = ex_is_greater_degrevlex::in_type(&add::tinfo_static).compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
+		cmpval = print_order().compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
 		if (cmpval != 0) {
 			return cmpval;
 		}
 
 		// compare coefficients
-	        cmpval = compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
+		cmpval = compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
 		if (cmpval != 0) {
 			return cmpval;
 		}
@@ -518,32 +499,27 @@
 // in add object:
 // first exponents
 // then bases
-int ex_is_greater_degrevlex::compare_power_symbol(const power *lh,
+int print_order_mul::compare_power_symbol(const power *lh,
 		const symbol *rh) const
 {
-        int cmpval;
+	int cmpval;
+	cmpval = compare(get_pointer(lh->basis.bp), rh);
+	if (cmpval != 0)
+		  return cmpval;
+	
+	cmpval = compare(get_pointer(lh->exponent.bp), _num1_p);
+	
+	return cmpval;
+}
 
-	//std::cout<<"in compare_power_symbol"<<std::endl;
-        if (in_type_id == &mul::tinfo_static) {
-	        cmpval = compare(get_pointer(lh->basis.bp), rh);
-		if (cmpval != 0)
-        		  return cmpval;
-		
-		cmpval = compare(get_pointer(lh->exponent.bp), _num1_p);
-		
-		return cmpval;
-	}
+int print_order::compare_power_symbol(const power *lh,
+		const symbol *rh) const
+{
+	int cmpval;
 
 	// We are in an add object
 	if (is_a<numeric>(lh->exponent)) {
-		numeric lh_exp = ex_to<numeric>(lh->exponent);
-		double lh_deg;
-		if (lh_exp.is_real()) {
-			lh_deg = lh_exp.to_double();
-		} else {
-			lh_deg = std::sqrt(std::pow(lh_exp.real().to_double(), 2) + 
-					std::pow(lh_exp.imag().to_double(), 2));
-		}
+		double lh_deg = numeric_to_double(ex_to<numeric>(lh->exponent));
 		if (lh_deg != 1)
 			return lh_deg < 1 ? -1 : 1;
 	}
@@ -561,90 +537,66 @@
 // in add object:
 // first exponents
 // then bases
-int ex_is_greater_degrevlex::compare_same_type_power(const power *lh,
-	        const power *rh) const
+int print_order_mul::compare_same_type_power(const power *lh,
+		const power *rh) const
 {
-        int cmpval;
-        if (in_type_id == &mul::tinfo_static) {
-	        cmpval = compare(get_pointer(lh->basis.bp), get_pointer(rh->basis.bp));
-		if (cmpval != 0)
-        		  return cmpval;
-		cmpval = compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
-		
-		return cmpval;
-	}
+	int cmpval;
+	cmpval = compare(get_pointer(lh->basis.bp), get_pointer(rh->basis.bp));
+	if (cmpval != 0)
+		  return cmpval;
+	cmpval = compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
+	
+	return cmpval;
+}
+int print_order::compare_same_type_power(const power *lh,
+		const power *rh) const
+{
+	int cmpval;
 
 	double lh_deg = 1;
 	double rh_deg = 1;
 	if (is_a<numeric>(lh->exponent)) {
-		numeric lh_exp = ex_to<numeric>(lh->exponent);
-		if (lh_exp.is_real()) {
-			lh_deg = lh_exp.to_double();
-		} else {
-			lh_deg = std::sqrt(std::pow(lh_exp.real().to_double(), 2) + 
-					std::pow(lh_exp.imag().to_double(), 2));
-		}
+		lh_deg = numeric_to_double(ex_to<numeric>(lh->exponent));
 	}
 	if (is_a<numeric>(rh->exponent)) {
-		numeric rh_exp = ex_to<numeric>(rh->exponent);
-		if (rh_exp.is_real()) {
-			rh_deg = rh_exp.to_double();
-		} else {
-			rh_deg = std::sqrt(std::pow(rh_exp.real().to_double(), 2) + 
-					std::pow(rh_exp.imag().to_double(), 2));
-		}
+		rh_deg = numeric_to_double(ex_to<numeric>(rh->exponent));
 	}
 	if (rh_deg != lh_deg)
 		return lh_deg < rh_deg ? -1 : 1;
 
-	cmpval = compare(get_pointer(lh->basis.bp),
-			 get_pointer(rh->basis.bp));
+	cmpval = compare(get_pointer(lh->basis.bp), get_pointer(rh->basis.bp));
 	if (cmpval != 0)
-        	return cmpval;
+		return cmpval;
 
 	if (is_a<numeric>(lh->exponent) && is_a<numeric>(rh->exponent))
-	        return 0;
-	return compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
+		return 0;
+	return compare(get_pointer(lh->exponent.bp),
+			get_pointer(rh->exponent.bp));
 }
 
 // compare two symbol objects
 // same behavior wihtin mul and add objects:
 // we compare names
-int ex_is_greater_degrevlex::compare_same_type_symbol(const symbol *lh,
+int print_order::compare_same_type_symbol(const symbol *lh,
 		const symbol *rh) const
 {
-        //std::cout<<"in compare_same symbol"<<std::endl;
-	//std::cout<<"lh: ";
-	//lh->dbgprint();
-	//std::cout<<"rh: ";
-	//rh->dbgprint();
-	//std::cout<<std::endl;
-
-        // Weird because Sage sorts based on creation order.
-        // SAGE/Pynac: Sorting based on creation order doesn't work for Sage.
-        // instead we sort on variable name. -- William Stein
-
-	//std::cout<<"comparing names: "<<(lh->name < rh->name)<<std::endl;
-	/* Reversed ordering on char encoding (i.e. "a" < "b") then length (i.e. "abc" < "abcd")
+	/* Reversed ordering on char encoding (i.e. "a" < "b") then length
+	 * (i.e. "abc" < "abcd")
 	   i.e. "x" > "y" and "xyz" > "xyzt" */
 	if (lh->serial==rh->serial) return 0;
-	//std::cout<<"after if"<<std::endl;
 	return lh->name < rh->name ? 1 : -1;
-
-	//return lh->serial < rh->serial ? 1 : -1;
-	//return -lh->compare_same_type(*rh);
 }
 
 // compare two containers of the same type
 template <template <class T, class = std::allocator<T> > class C>
-int ex_is_greater_degrevlex::compare_same_type_container(const container<C> *lh,
+int print_order::compare_same_type_container(const container<C> *lh,
 							 const container<C> *rh) const
 {
-        typename C<ex>::const_iterator it1 = lh->seq.begin(), it1end = lh->seq.end(),
-	                      it2 = rh->seq.begin(), it2end = rh->seq.end();
+	typename C<ex>::const_iterator it1 = lh->seq.begin(), it1end = lh->seq.end(),
+			      it2 = rh->seq.begin(), it2end = rh->seq.end();
 
 	while (it1 != it1end && it2 != it2end) {
-	        int cmpval = compare(get_pointer(it1->bp), get_pointer(it2->bp));
+		int cmpval = compare(get_pointer(it1->bp), get_pointer(it2->bp));
 		if (cmpval)
 			return cmpval;
 		++it1; ++it2;
@@ -656,33 +608,27 @@
 // compare two function objects
 // same behavior wihtin mul and add objects:
 // we compare names
-int ex_is_greater_degrevlex::compare_same_type_function(const function *lh,
+int print_order::compare_same_type_function(const function *lh,
 		const function *rh) const
 {
 
-	//std::cout<<"comparing names: "<<(lh->get_name() < rh->get_name())<<std::endl;
-	/* Reversed ordering on char encoding (i.e. "a" < "b") then length (i.e. "abc" < "abcd")
-	   i.e. "x" > "y" and "xyz" > "xyzt" */
-        if (lh->serial==rh->serial) //return 0;
-	        return compare_same_type_container(lh,rh);
-	//std::cout<<"after if"<<std::endl;
+	if (lh->serial==rh->serial)
+		return compare_same_type_container(lh,rh);
 	return lh->get_name() < rh->get_name() ? 1 : -1;	
 
-	//return lh->serial < rh->serial ? 1 : -1;
-	//return -lh->compare_same_type(*rh);
 }
 
 // compare two fderivative objects
 // same behavior wihtin mul and add objects:
 // we compare names
-int ex_is_greater_degrevlex::compare_same_type_fderivative(const fderivative *lh,
+int print_order::compare_same_type_fderivative(const fderivative *lh,
 		const fderivative *rh) const
 {
-        int cmpval = compare_same_type_function(lh, rh);
+	int cmpval = compare_same_type_function(lh, rh);
 	if (cmpval != 0)
-	        return cmpval;
+		return cmpval;
 	if (lh->parameter_set != rh->parameter_set)
-	        return lh->parameter_set < rh->parameter_set ? -1 : 1;
+		return lh->parameter_set < rh->parameter_set ? 1 : -1;
 	return 0;
 }
 
diff --git a/ginac/order.h b/ginac/order.h
--- a/ginac/order.h
+++ b/ginac/order.h
@@ -35,7 +35,7 @@
 
 namespace GiNaC {
 
-struct ex_is_greater_degrevlex : public std::binary_function<ex, ex, bool> {
+class print_order : public std::binary_function<ex, ex, bool> {
 	const tinfo_t function_id;// = find_tinfo_key("function");
 	const tinfo_t fderivative_id;// = find_tinfo_key("fderivative");
 	const tinfo_t power_id;// = find_tinfo_key("power");
@@ -44,9 +44,9 @@
 	const tinfo_t add_id;// = find_tinfo_key("add");
 	const tinfo_t numeric_id;// = find_tinfo_key("numeric");
 	const tinfo_t constant_id;// = find_tinfo_key("constant");
-	const tinfo_t in_type_id;
 
-	ex_is_greater_degrevlex(const tinfo_t type_id):
+	public:
+	print_order():
 		function_id(find_tinfo_key("function")),
 		fderivative_id(find_tinfo_key("fderivative")),
 		power_id(find_tinfo_key("power")),
@@ -54,8 +54,7 @@
 		mul_id(find_tinfo_key("mul")),
 		add_id(find_tinfo_key("add")),
 		numeric_id(find_tinfo_key("numeric")),
-		constant_id(find_tinfo_key("constant")),
-		in_type_id(type_id) {};
+		constant_id(find_tinfo_key("constant")) {};
 
 	bool operator() (const ex &lh, const ex &rh) const;
 	int compare(const ex &lh, const ex &rh) const;
@@ -70,8 +69,8 @@
 	int compare_add_mul(const add *lh, const mul *rh) const;
 	int compare_same_type_add(const add *lh, const add *rh) const;
 	// power objects
-	int compare_power_symbol(const power *lh, const symbol *rh) const;
-	int compare_same_type_power(const power *lh, const power *rh) const;
+	virtual int compare_power_symbol(const power *lh, const symbol *rh) const;
+	virtual int compare_same_type_power(const power *lh, const power *rh) const;
 	// symbol objects
 	int compare_same_type_symbol(const symbol *lh, const symbol *rh) const;
 	// container objects
@@ -81,51 +80,26 @@
 	int compare_same_type_function(const function *lh, const function *rh) const;
 	// fderivative objects
 	int compare_same_type_fderivative(const fderivative *lh, const fderivative *rh) const;
+};
 
-	static const ex_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
-	  static ex_is_greater_degrevlex in_type[2] = {ex_is_greater_degrevlex(&add::tinfo_static),
-						       ex_is_greater_degrevlex(&mul::tinfo_static)};
-	        if (in_type_id == &mul::tinfo_static)
-		        return in_type[1];
-        	return in_type[0];
-	}
+class print_order_mul : public print_order {
+	int compare_power_symbol(const power *lh, const symbol *rh) const;
+	int compare_same_type_power(const power *lh, const power *rh) const;
 };
 
 // We have to define the following class to sort held expressions
 // E.g. 3*x+2*x which does not get simplified to 5*x.
-struct expair_is_greater_degrevlex : public std::binary_function<expair, expair, bool>
+struct print_order_pair : \
+		public std::binary_function<expair, expair, bool>
 {
-        const tinfo_t in_type_id;
-        expair_is_greater_degrevlex(tinfo_t in_type):
-	        in_type_id(in_type) {};
 	bool operator() (const expair &lh, const expair &rh) const;
-
-	static const expair_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
-        	static expair_is_greater_degrevlex in_type[2] = {expair_is_greater_degrevlex(&add::tinfo_static),expair_is_greater_degrevlex(&add::tinfo_static)};
-		if (in_type_id == &mul::tinfo_static)
-		        return in_type[1];
-        	return in_type[0];
-	}
+	bool compare_degrees(const expair &lhex, const expair &rhex) const;
 };
 
-struct expair_rest_is_greater_degrevlex : public std::binary_function<expair, expair, bool>
+struct print_order_pair_mul : public print_order_pair
 {
-        const tinfo_t in_type_id;
-        expair_rest_is_greater_degrevlex(tinfo_t in_type):
-	        in_type_id(in_type) {};
-	bool operator() (const expair &lh, const expair &rh) const {
-	        return ex_is_greater_degrevlex::in_type(in_type_id)(lh.rest, rh.rest);
-	}
-
-	static const expair_rest_is_greater_degrevlex& in_type(tinfo_t in_type_id) {
-        	static expair_rest_is_greater_degrevlex in_type[2] = {expair_rest_is_greater_degrevlex(&add::tinfo_static),
-					expair_rest_is_greater_degrevlex(&mul::tinfo_static)};
-		if (in_type_id == &mul::tinfo_static)
-		        return in_type[1];
-        	return in_type[0];
-	}
+	bool operator() (const expair &lh, const expair &rh) const;
 };
 
 } // namespace GiNaC
-
 #endif // ndef __GINAC_ORDER_H__
diff --git a/ginac/power.h b/ginac/power.h
--- a/ginac/power.h
+++ b/ginac/power.h
@@ -40,7 +40,8 @@
 {
 	GINAC_DECLARE_REGISTERED_CLASS(power, basic)
 	
-	friend struct ex_is_greater_degrevlex;
+	friend struct print_order;
+	friend struct print_order_mul;
 	friend class mul;
 	
 // member functions
diff --git a/ginac/symbol.h b/ginac/symbol.h
--- a/ginac/symbol.h
+++ b/ginac/symbol.h
@@ -43,7 +43,7 @@
 
 	friend class realsymbol;
 	friend class possymbol;
-	friend struct ex_is_greater_degrevlex;
+	friend struct print_order;
 
 // types