- deleted add::printpair() since this has become obsolete
[ginac.git] / ginac / print.cpp
1 /** @file print.cpp
2  *
3  *  The methods .print() are responsible for the nice default-output of
4  *  objects.  All related helper-functions go in here as well. */
5
6 /*
7  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <iostream>
25
26 #include "basic.h"
27 #include "ex.h"
28 #include "add.h"
29 #include "constant.h"
30 #include "expairseq.h"
31 #include "fail.h"
32 #include "indexed.h"
33 #include "inifcns.h"
34 #include "matrix.h"
35 #include "mul.h"
36 #include "ncmul.h"
37 #include "numeric.h"
38 #include "power.h"
39 #include "relational.h"
40 #include "series.h"
41 #include "symbol.h"
42 #include "debugmsg.h"
43
44 namespace GiNaC {
45
46 void ex::print(ostream & os, unsigned upper_precedence) const
47 {
48     debugmsg("ex print",LOGLEVEL_PRINT);
49     ASSERT(bp!=0);
50     bp->print(os,upper_precedence);
51 }
52
53 void ex::dbgprint(void) const
54 {
55     debugmsg("ex dbgprint",LOGLEVEL_PRINT);
56     ASSERT(bp!=0);
57     bp->dbgprint();
58 }
59
60 void basic::print(ostream & os, unsigned upper_precedence) const
61 {
62     debugmsg("basic print",LOGLEVEL_PRINT);
63     os << "[basic object]";
64 }
65
66 void basic::dbgprint(void) const
67 {
68     print(cerr);
69     cerr << endl;
70 }
71
72 void symbol::print(ostream & os, unsigned upper_precedence) const
73 {
74     debugmsg("symbol print",LOGLEVEL_PRINT);
75     os << name;
76 }
77
78 void constant::print(ostream & os, unsigned upper_precedence) const
79 {
80     debugmsg("constant print",LOGLEVEL_PRINT);
81     os << name;
82 }
83
84 void power::print(ostream & os, unsigned upper_precedence) const
85 {
86     debugmsg("power print",LOGLEVEL_PRINT);
87 #if 1
88     if (precedence<=upper_precedence) os << "(";
89     basis.print(os,precedence);
90     os << "^";
91     exponent.print(os,precedence);
92     if (precedence<=upper_precedence) os << ")";
93 #else
94     os << "pow(" << basis << "," << exponent << ")";
95 #endif
96 }
97
98 void fail::print(ostream & os, unsigned upper_precedence) const
99 {
100     debugmsg("fail print",LOGLEVEL_PRINT);
101     os << "FAIL";
102 }
103
104 void expairseq::printpair(ostream & os, expair const & p, unsigned upper_precedence) const
105 {
106     os << "[[";
107     p.rest.bp->print(os,precedence);
108     os << ",";
109     p.coeff.bp->print(os,precedence);
110     os << "]]";
111 }
112
113 /*
114 void expairseq::printseq(ostream & os, char delim, unsigned this_precedence,
115                          unsigned upper_precedence) const
116 {
117     if (this_precedence<=upper_precedence) os << "(";
118     epvector::const_iterator itt,it,it_last,it_start;
119     it_last=seq.end();
120     --it_last;
121     it_start=seq.begin();
122
123     switch (delim) {
124     case '+':
125         for (it=seq.begin(); it!=it_last; ++it) {
126             itt = it +1;
127             expair const & k = *itt;
128             printpair(os,*it, this_precedence);
129             if (((is_ex_of_type(k.rest, numeric)) && (k.coeff*k.rest > 0) ) || ((!is_ex_of_type(k.rest, numeric)) && (k.coeff >0))){
130                 os << "+";
131             }
132         }
133         printpair(os,*it,this_precedence);
134         break;
135         
136     case '*':
137         for (it = it_last ; it!=it_start; --it) {
138             if ((*it).rest.is_equal(exMINUSONE()) &&
139                 (*it).coeff.is_equal(exONE())) {
140                 os << "-";
141             } else {
142                 printpair(os, *it,this_precedence);
143                 os << delim;
144             }
145         }
146         printpair(os,*it,this_precedence);
147         break;
148     default:
149         clog << "Nobody expects the Spanish Inquisition: "
150              << "deliminator unknown!" << endl;
151     }
152     if (this_precedence<=upper_precedence) os << ")";
153 }
154 */
155
156 void expairseq::printseq(ostream & os, char delim, unsigned this_precedence,
157                          unsigned upper_precedence) const
158 {
159     if (this_precedence<=upper_precedence) os << "(";
160     epvector::const_iterator it,it_last;
161     it_last=seq.end();
162     --it_last;
163     for (it=seq.begin(); it!=it_last; ++it) {
164         printpair(os,*it,this_precedence);
165         os << delim;
166     }
167     printpair(os,*it,this_precedence);
168     if (!overall_coeff.is_equal(default_overall_coeff())) {
169         os << delim << overall_coeff;
170     }
171     if (this_precedence<=upper_precedence) os << ")";
172 }
173     
174 void expairseq::print(ostream & os, unsigned upper_precedence) const
175 {
176     debugmsg("expairseq print",LOGLEVEL_PRINT);
177     os << "[[";
178     printseq(os,',',precedence,upper_precedence);
179     os << "]]";
180 }
181
182 void add::print(ostream & os, unsigned upper_precedence) const
183 {
184     debugmsg("add print",LOGLEVEL_PRINT);
185     if (precedence<=upper_precedence) os << "(";
186     numeric coeff;
187     bool first=true;
188     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
189         coeff = ex_to_numeric(cit->coeff);
190         if (!first) {
191             if (coeff < 0) os << '-'; else os << '+';
192         } else {
193             if (coeff < 0) os << '-';
194             first=false;
195         }
196         if (coeff.compare(numONE()) && coeff.compare(numMINUSONE())) {
197             if (!coeff.is_real() && !coeff.real().is_zero()) os << '(';
198             if (coeff > 0)
199                 os << coeff;
200             else
201                 os << numeric(-1)*coeff;
202             if (!coeff.is_real() && !coeff.real().is_zero()) os << ')';
203             os << '*';
204         }
205         os << cit->rest;
206     }
207     // print the overall numeric coefficient, if present:
208     if (!overall_coeff.is_zero()) {
209         if (overall_coeff > 0) os << '+';
210         os << overall_coeff;
211     }
212     if (precedence<=upper_precedence) os << ")";
213 }
214
215 void mul::print(ostream & os, unsigned upper_precedence) const
216 {
217     debugmsg("mul print",LOGLEVEL_PRINT);
218     if (precedence<=upper_precedence) os << "(";
219     bool first=true;
220     if (!overall_coeff.is_equal(exONE())) {
221         overall_coeff.print(os,precedence);
222         first=false;
223     }
224     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
225         if (!first) {
226             os << '*';
227         } else {
228             first=false;
229         }
230         recombine_pair_to_ex(*cit).print(os,precedence);
231     }
232     if (precedence<=upper_precedence) os << ")";
233 }
234
235 void ncmul::print(ostream & os, unsigned upper_precedence) const
236 {
237     debugmsg("ncmul print",LOGLEVEL_PRINT);
238     printseq(os,'(','%',')',precedence,upper_precedence);
239 }
240
241 /*void function::print(ostream & os, unsigned upper_precedence) const
242  *{
243  *    debugmsg("function print",LOGLEVEL_PRINT);
244  *    os << name;
245  *    printseq(os,'(',',',')',exprseq::precedence,function::precedence);
246  *}*/
247
248 void series::print(ostream &os, unsigned upper_precedence) const
249 {
250         debugmsg("symbol print", LOGLEVEL_PRINT);
251         convert_to_poly().print(os, upper_precedence);
252 }
253
254 void relational::print(ostream & os, unsigned upper_precedence) const
255 {
256     debugmsg("relational print",LOGLEVEL_PRINT);
257     if (precedence<=upper_precedence) os << "(";
258     lh.print(os,precedence);
259     switch (o) {
260     case equal:
261         os << "==";
262         break;
263     case not_equal:
264         os << "!=";
265         break;
266     case less:
267         os << "<";
268         break;
269     case less_or_equal:
270         os << "<=";
271         break;
272     case greater:
273         os << ">";
274         break;
275     case greater_or_equal:
276         os << ">=";
277         break;
278     default:
279         os << "(INVALID RELATIONAL OPERATOR)";
280     }
281     rh.print(os,precedence);
282     if (precedence<=upper_precedence) os << ")";
283 }
284
285 void matrix::print(ostream & os, unsigned upper_precedence) const
286 {
287     debugmsg("matrix print",LOGLEVEL_PRINT);
288     os << "[[ ";
289     for (int r=0; r<row-1; ++r) {
290         os << "[[";
291         for (int c=0; c<col-1; ++c) {
292             os << m[r*col+c] << ",";
293         }
294         os << m[col*(r+1)-1] << "]], ";
295     }
296     os << "[[";
297     for (int c=0; c<col-1; ++c) {
298         os << m[(row-1)*col+c] << ",";
299     }
300     os << m[row*col-1] << "]] ]]";
301 }
302
303 } // namespace GiNaC