]> www.ginac.de Git - ginac.git/blob - ginac/expair.h
- indentation is now done with tabs
[ginac.git] / ginac / expair.h
1 /** @file expair.h
2  *
3  *  Definition of expression pairs (building blocks of expairseq). */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2000 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #ifndef __GINAC_EXPAIR_H__
24 #define __GINAC_EXPAIR_H__
25
26 #include "ex.h"
27 #include "numeric.h"
28
29 #ifndef NO_NAMESPACE_GINAC
30 namespace GiNaC {
31 #endif // ndef NO_NAMESPACE_GINAC
32
33 /** A pair of expressions.
34  *  This similar to, but slightly extended STL's pair<> but we need to account
35  *  for methods like .compare() */
36 class expair
37 {
38 public:
39         expair() {}
40         ~expair() {}
41         expair(const expair & other) : rest(other.rest), coeff(other.coeff)
42         {
43                 GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
44         }
45         const expair & operator=(const expair & other)
46         {
47                 if (this != &other) {
48                         rest=other.rest;
49                         coeff=other.coeff;
50                 }
51                 return *this;
52         }
53         expair(const ex & r, const ex & c) : rest(r), coeff(c)
54         {
55                 GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
56         }
57         
58         bool is_numeric_with_coeff_1(void) const
59         {
60                 GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
61                 return is_ex_exactly_of_type(rest,numeric) &&
62                            (coeff.is_equal(ex(1)));
63         }
64
65         bool is_equal(const expair & other) const
66         {
67                 return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
68         }
69         bool is_less(const expair & other) const 
70         {
71                 return (rest.compare(other.rest)<0) ||
72                            (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
73         }
74         int compare(const expair & other) const
75         {
76                 int cmpval=rest.compare(other.rest);
77                 if (cmpval!=0) return cmpval;
78                 cmpval=coeff.compare(other.coeff);
79                 return cmpval;
80         }
81
82         bool is_less_old2(const expair & other) const 
83         {
84                 /*
85                 bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
86                 bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
87                 if (this_numeric_with_coeff_1) {
88                         if (other_numeric_with_coeff_1) {
89                                 // both have coeff 1: compare rests
90                                 return rest.compare(other.rest)<0;
91                         }
92                         // only this has coeff 1: >
93                         return false;
94                 } else if (other_numeric_with_coeff_1) {
95                         // only other has coeff 1: <
96                         return true;
97                 }
98                 return (rest.compare(other.rest)<0) ||
99                            (!(other.rest.compare(rest)<0) &&
100                                  (coeff.compare(other.coeff)<0));
101                 */
102                 if (is_ex_exactly_of_type(rest,numeric) &&
103                         is_ex_exactly_of_type(other.rest,numeric)) {
104                         if (coeff.is_equal(ex(1))) {
105                                 if ((other.coeff).is_equal(ex(1))) {
106                                         // both have coeff 1: compare rests
107                                         return rest.compare(other.rest)<0;
108                                 }
109                                 // only this has coeff 1: >
110                                 return false;
111                         } else if ((other.coeff).is_equal(ex(1))) {
112                                 // only other has coeff 1: <
113                                 return true;
114                         }
115                         // neither has coeff 1: usual compare        
116                 }
117                 return (rest.compare(other.rest)<0) ||
118                            (!(other.rest.compare(rest)<0) &&
119                                  (coeff.compare(other.coeff)<0));
120         }
121         int compare_old2(const expair & other) const
122         {
123                 if (is_ex_exactly_of_type(rest,numeric) &&
124                         is_ex_exactly_of_type(other.rest,numeric)) {
125                         if ((coeff).is_equal(ex(1))) {
126                                 if ((other.coeff).is_equal(ex(1))) {
127                                         // both have coeff 1: compare rests
128                                         return rest.compare(other.rest);
129                                 }
130                                 // only this has coeff 1: >
131                                 return 1;
132                         } else if ((other.coeff).is_equal(ex(1))) {
133                                 // only other has coeff 1: <
134                                 return -1;
135                         }
136                         // neither has coeff 1: usual compare        
137                 }
138                 /*
139                 bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
140                 bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
141                 if (this_numeric_with_coeff_1) {
142                         if (other_numeric_with_coeff_1) {
143                                 // both have coeff 1: compare rests
144                                 return rest.compare(other.rest);
145                         }
146                         // only this has coeff 1: >
147                         return 1;
148                 } else if (other_numeric_with_coeff_1) {
149                         // only other has coeff 1: <
150                         return -1;
151                         // neither has coeff 1: usual compare        
152                 }
153                 */
154                 int cmpval=rest.compare(other.rest);
155                 if (cmpval!=0) return cmpval;
156                 return coeff.compare(other.coeff);
157         }
158         bool is_less_old(const expair & other) const 
159         {
160                 return (rest.compare(other.rest)<0) ||
161                            (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
162         }
163         int compare_old(const expair & other) const
164         {
165                 int cmpval=rest.compare(other.rest);
166                 if (cmpval!=0) return cmpval;
167                 cmpval=coeff.compare(other.coeff);
168                 return cmpval;
169         }
170
171         void printraw(std::ostream & os) const
172         {
173                 os << "expair(";
174                 rest.printraw(os);
175                 os << ",";
176                 coeff.printraw(os);
177                 os << ")";
178         }
179
180         ex rest;
181         ex coeff;
182 };
183
184 class expair_is_less
185 {
186 public:
187         bool operator()(const expair & lh, const expair & rh) const
188         {
189                 return lh.is_less(rh);
190         }
191 };
192
193 class expair_is_less_old
194 {
195 public:
196         bool operator()(const expair & lh, const expair & rh) const
197         {
198                 return lh.is_less_old(rh);
199         }
200 };
201
202 #ifndef NO_NAMESPACE_GINAC
203 } // namespace GiNaC
204 #endif // ndef NO_NAMESPACE_GINAC
205
206 #endif // ndef __GINAC_EXPAIR_H__