#ifndef around namespace GiNaC { }
[ginac.git] / ginac / printtree.cpp
1 /** @file printtree.cpp
2  *
3  * print in tree- (indented-) form, so developers can have a look at the
4  * underlying structure. */
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 #include <math.h>
26
27 #include "basic.h"
28 #include "ex.h"
29 #include "add.h"
30 #include "constant.h"
31 #include "expairseq.h"
32 #include "indexed.h"
33 #include "inifcns.h"
34 #include "mul.h"
35 #include "ncmul.h"
36 #include "numeric.h"
37 #include "power.h"
38 #include "relational.h"
39 #include "series.h"
40 #include "symbol.h"
41 #include "debugmsg.h"
42
43 #ifndef NO_GINAC_NAMESPACE
44 namespace GiNaC {
45 #endif // ndef NO_GINAC_NAMESPACE
46
47 void ex::printtree(ostream & os, unsigned indent) const
48 {
49     debugmsg("ex printtree",LOGLEVEL_PRINT);
50     GINAC_ASSERT(bp!=0);
51     // os << "refcount=" << bp->refcount << " ";
52     bp->printtree(os,indent);
53 }
54
55 void ex::dbgprinttree(void) const
56 {
57     debugmsg("ex dbgprinttree",LOGLEVEL_PRINT);
58     GINAC_ASSERT(bp!=0);
59     bp->dbgprinttree();
60 }
61
62 void basic::printtree(ostream & os, unsigned indent) const
63 {
64     debugmsg("basic printtree",LOGLEVEL_PRINT);
65     os << string(indent,' ') << "type=" << typeid(*this).name()
66        << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
67        << ", flags=" << flags
68        << ", nops=" << nops() << endl;
69     for (int i=0; i<nops(); ++i) {
70         op(i).printtree(os,indent+delta_indent);
71     }
72 }
73
74 void basic::dbgprinttree(void) const
75 {
76     printtree(cerr,0);
77 }
78
79 void numeric::printtree(ostream & os, unsigned indent) const
80 {
81     debugmsg("numeric printtree", LOGLEVEL_PRINT);
82     // We are cheating here, because we don't want to include the underlying
83     // bignum package's headers again, so we use ostream::operator<<(numeric):
84     os << string(indent,' ');
85     (*this).print(os);
86     os << " (numeric): "
87        << "hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
88        << ", flags=" << flags << endl;
89 }
90
91 void symbol::printtree(ostream & os, unsigned indent) const
92 {
93     debugmsg("symbol printtree",LOGLEVEL_PRINT);
94     os << string(indent,' ') << name << " (symbol): "
95        << "serial=" << serial
96        << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
97        << ", flags=" << flags << endl;
98 }
99
100 void power::printtree(ostream & os, unsigned indent) const
101 {
102     debugmsg("power printtree",LOGLEVEL_PRINT);
103
104     os << string(indent,' ') << "power: "
105        << "hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
106        << ", flags=" << flags << endl;
107     basis.printtree(os,indent+delta_indent);
108     exponent.printtree(os,indent+delta_indent);
109 }
110
111 void expairseq::printtree(ostream & os, unsigned indent) const
112 {
113     debugmsg("expairseq printtree",LOGLEVEL_PRINT);
114
115     os << string(indent,' ') << "type=" << typeid(*this).name()
116        << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
117        << ", flags=" << flags
118        << ", nops=" << nops() << endl;
119     for (unsigned i=0; i<seq.size(); ++i) {
120         seq[i].rest.printtree(os,indent+delta_indent);
121         seq[i].coeff.printtree(os,indent+delta_indent);
122         if (i!=seq.size()-1) {
123             os << string(indent+delta_indent,' ') << "-----" << endl;
124         }
125     }
126     if (!overall_coeff.is_equal(default_overall_coeff())) {
127         os << string(indent+delta_indent,' ') << "-----" << endl;
128         os << string(indent+delta_indent,' ') << "overall_coeff" << endl;
129         overall_coeff.printtree(os,indent+delta_indent);
130     }
131     os << string(indent+delta_indent,' ') << "=====" << endl;
132 #ifdef EXPAIRSEQ_USE_HASHTAB
133     os << string(indent+delta_indent,' ')
134        << "hashtab size " << hashtabsize << endl;
135     if (hashtabsize==0) return;
136 #define MAXCOUNT 5
137     unsigned count[MAXCOUNT+1];
138     for (int i=0; i<MAXCOUNT+1; ++i) count[i]=0;
139     unsigned this_bin_fill;
140     unsigned cum_fill_sq=0;
141     unsigned cum_fill=0;
142     for (unsigned i=0; i<hashtabsize; ++i) {
143         this_bin_fill=0;
144         if (hashtab[i].size()>0) {
145             os << string(indent+delta_indent,' ') 
146                << "bin " << i << " with entries ";
147             for (epplist::const_iterator it=hashtab[i].begin();
148                  it!=hashtab[i].end(); ++it) {
149                 os << *it-seq.begin() << " ";
150                 this_bin_fill++;
151             }
152             os << endl;
153             cum_fill += this_bin_fill;
154             cum_fill_sq += this_bin_fill*this_bin_fill;
155         }
156         if (this_bin_fill<MAXCOUNT) {
157             ++count[this_bin_fill];
158         } else {
159             ++count[MAXCOUNT];
160         }
161     }
162     unsigned fact=1;
163     double cum_prob=0;
164     double lambda=(1.0*seq.size())/hashtabsize;
165     for (int k=0; k<MAXCOUNT; ++k) {
166         if (k>0) fact *= k;
167         double prob=pow(lambda,k)/fact*exp(-lambda);
168         cum_prob += prob;
169         os << string(indent+delta_indent,' ') << "bins with " << k << " entries: "
170            << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
171            << int(prob*1000)/10.0 << ")" << endl;
172     }
173     os << string(indent+delta_indent,' ') << "bins with more entries: "
174        << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: "
175        << int((1-cum_prob)*1000)/10.0 << ")" << endl;
176     
177     os << string(indent+delta_indent,' ') << "variance: "
178        << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill)
179        << endl;
180     os << string(indent+delta_indent,' ') << "average fill: "
181        << (1.0*cum_fill)/hashtabsize
182        << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << endl;
183 #endif // def EXPAIRSEQ_USE_HASHTAB
184 }
185
186 #ifndef NO_GINAC_NAMESPACE
187 } // namespace GiNaC
188 #endif // ndef NO_GINAC_NAMESPACE