]> www.ginac.de Git - ginac.git/blob - ginac/printtree.cpp
81881988ef85dce81ff64e2d778639ad3b488dca
[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 #include <iostream>
7 #include <math.h>
8
9 #include "ginac.h"
10
11 void ex::printtree(ostream & os, unsigned indent) const
12 {
13     debugmsg("ex printtree",LOGLEVEL_PRINT);
14     ASSERT(bp!=0);
15     // os << "refcount=" << bp->refcount << " ";
16     bp->printtree(os,indent);
17 }
18
19 void ex::dbgprinttree(void) const
20 {
21     debugmsg("ex dbgprinttree",LOGLEVEL_PRINT);
22     ASSERT(bp!=0);
23     bp->dbgprinttree();
24 }
25
26 void basic::printtree(ostream & os, unsigned indent) const
27 {
28     debugmsg("basic printtree",LOGLEVEL_PRINT);
29     os << string(indent,' ') << "type=" << typeid(*this).name()
30        << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
31        << ", flags=" << flags
32        << ", nops=" << nops() << endl;
33     for (int i=0; i<nops(); ++i) {
34         op(i).printtree(os,indent+delta_indent);
35     }
36 }
37
38 void basic::dbgprinttree(void) const
39 {
40     printtree(cerr,0);
41 }
42
43 void numeric::printtree(ostream & os, unsigned indent) const
44 {
45     debugmsg("numeric printtree", LOGLEVEL_PRINT);
46     // We are cheating here, because we don't want to include the underlying
47     // bignum package's headers again, so we use ostream::operator<<(numeric):
48     os << string(indent,' ');
49     (*this).print(os);
50     os << " (numeric): "
51        << "hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
52        << ", flags=" << flags << endl;
53 }
54
55 void symbol::printtree(ostream & os, unsigned indent) const
56 {
57     debugmsg("symbol printtree",LOGLEVEL_PRINT);
58     os << string(indent,' ') << name << " (symbol): "
59        << "serial=" << serial
60        << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
61        << ", flags=" << flags << endl;
62 }
63
64 void power::printtree(ostream & os, unsigned indent) const
65 {
66     debugmsg("power printtree",LOGLEVEL_PRINT);
67
68     os << string(indent,' ') << "power: "
69        << "hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
70        << ", flags=" << flags << endl;
71     basis.printtree(os,indent+delta_indent);
72     exponent.printtree(os,indent+delta_indent);
73 }
74
75 void expairseq::printtree(ostream & os, unsigned indent) const
76 {
77     debugmsg("expairseq printtree",LOGLEVEL_PRINT);
78
79     os << string(indent,' ') << "type=" << typeid(*this).name()
80        << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
81        << ", flags=" << flags
82        << ", nops=" << nops() << endl;
83     for (unsigned i=0; i<seq.size(); ++i) {
84         seq[i].rest.printtree(os,indent+delta_indent);
85         seq[i].coeff.printtree(os,indent+delta_indent);
86         if (i!=seq.size()-1) {
87             os << string(indent+delta_indent,' ') << "-----" << endl;
88         }
89     }
90     if (!overall_coeff.is_equal(default_overall_coeff())) {
91         os << string(indent+delta_indent,' ') << "-----" << endl;
92         os << string(indent+delta_indent,' ') << "overall_coeff" << endl;
93         overall_coeff.printtree(os,indent+delta_indent);
94     }
95     os << string(indent+delta_indent,' ') << "=====" << endl;
96 #ifdef EXPAIRSEQ_USE_HASHTAB
97     os << string(indent+delta_indent,' ')
98        << "hashtab size " << hashtabsize << endl;
99     if (hashtabsize==0) return;
100 #define MAXCOUNT 5
101     unsigned count[MAXCOUNT+1];
102     for (int i=0; i<MAXCOUNT+1; ++i) count[i]=0;
103     unsigned this_bin_fill;
104     unsigned cum_fill_sq=0;
105     unsigned cum_fill=0;
106     for (unsigned i=0; i<hashtabsize; ++i) {
107         this_bin_fill=0;
108         if (hashtab[i].size()>0) {
109             os << string(indent+delta_indent,' ') 
110                << "bin " << i << " with entries ";
111             for (epplist::const_iterator it=hashtab[i].begin();
112                  it!=hashtab[i].end(); ++it) {
113                 os << *it-seq.begin() << " ";
114                 this_bin_fill++;
115             }
116             os << endl;
117             cum_fill += this_bin_fill;
118             cum_fill_sq += this_bin_fill*this_bin_fill;
119         }
120         if (this_bin_fill<MAXCOUNT) {
121             ++count[this_bin_fill];
122         } else {
123             ++count[MAXCOUNT];
124         }
125     }
126     unsigned fact=1;
127     double cum_prob=0;
128     double lambda=(1.0*seq.size())/hashtabsize;
129     for (int k=0; k<MAXCOUNT; ++k) {
130         if (k>0) fact *= k;
131         double prob=pow(lambda,k)/fact*exp(-lambda);
132         cum_prob += prob;
133         os << string(indent+delta_indent,' ') << "bins with " << k << " entries: "
134            << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
135            << int(prob*1000)/10.0 << ")" << endl;
136     }
137     os << string(indent+delta_indent,' ') << "bins with more entries: "
138        << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: "
139        << int((1-cum_prob)*1000)/10.0 << ")" << endl;
140     
141     os << string(indent+delta_indent,' ') << "variance: "
142        << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill)
143        << endl;
144     os << string(indent+delta_indent,' ') << "average fill: "
145        << (1.0*cum_fill)/hashtabsize
146        << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << endl;
147 #endif // def EXPAIRSEQ_USE_HASHTAB
148 }
149