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