]> www.ginac.de Git - ginac.git/blob - ginac/utils.cpp
8085ba3bdeb38673b7d0d3fadf2282765a4901ee
[ginac.git] / ginac / utils.cpp
1 /** @file utils.cpp
2  *
3  *  Implementation of several small and furry utilities needed within GiNaC
4  *  but not of any interest to the user of the library. */
5
6 /*
7  *  GiNaC Copyright (C) 1999-2017 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23
24 #include "ex.h"
25 #include "numeric.h"
26 #include "utils.h"
27 #include "version.h"
28
29 namespace GiNaC {
30
31 /* Version information buried into the library */
32 const int version_major = GINACLIB_MAJOR_VERSION;
33 const int version_minor = GINACLIB_MINOR_VERSION;
34 const int version_micro = GINACLIB_MICRO_VERSION;
35
36
37 /** ctor for pole_error exception class. */
38 pole_error::pole_error(const std::string& what_arg, int degree)
39         : domain_error(what_arg), deg(degree) { }
40
41 /** Return the degree of the pole_error exception class. */
42 int pole_error::degree() const
43 {
44         return deg;
45 }
46
47 /** Integer binary logarithm */
48 unsigned log2(unsigned n)
49 {
50         unsigned k;
51         for (k = 0; n > 1; n >>= 1)
52                 ++k;
53         return k;
54 }
55
56 /** Compute the multinomial coefficient n!/(p1!*p2!*...*pk!) where
57  *  n = p1+p2+...+pk, i.e. p is a partition of n.
58  */
59 const numeric
60 multinomial_coefficient(const std::vector<unsigned> & p)
61 {
62         numeric n = 0, d = 1;
63         for (auto & it : p) {
64                 n = n.add(numeric(it));
65                 d = d.mul(factorial(numeric(it)));
66         }
67         return factorial(n).div(d);
68 }
69
70 //////////
71 // flyweight chest of numbers is initialized here:
72 //////////
73
74 /** How many static objects were created?  Only the first one must create
75  *  the static flyweights on the heap. */
76 int library_init::count = 0;
77
78 // static numeric -120
79 const numeric *_num_120_p;
80 const ex _ex_120 = _ex_120;
81
82 // static numeric -60
83 const numeric *_num_60_p;
84 const ex _ex_60 = _ex_60;
85
86 // static numeric -48
87 const numeric *_num_48_p;
88 const ex _ex_48 = _ex_48;
89
90 // static numeric -30
91 const numeric *_num_30_p;
92 const ex _ex_30 = _ex_30;
93
94 // static numeric -25
95 const numeric *_num_25_p;
96 const ex _ex_25 = _ex_25;
97
98 // static numeric -24
99 const numeric *_num_24_p;
100 const ex _ex_24 = _ex_24;
101
102 // static numeric -20
103 const numeric *_num_20_p;
104 const ex _ex_20 = _ex_20;
105
106 // static numeric -18
107 const numeric *_num_18_p;
108 const ex _ex_18 = _ex_18;
109
110 // static numeric -15
111 const numeric *_num_15_p;
112 const ex _ex_15 = _ex_15;
113
114 // static numeric -12
115 const numeric *_num_12_p;
116 const ex _ex_12 = _ex_12;
117
118 // static numeric -11
119 const numeric *_num_11_p;
120 const ex _ex_11 = _ex_11;
121
122 // static numeric -10
123 const numeric *_num_10_p;
124 const ex _ex_10 = _ex_10;
125
126 // static numeric -9
127 const numeric *_num_9_p;
128 const ex _ex_9 = _ex_9;
129
130 // static numeric -8
131 const numeric *_num_8_p;
132 const ex _ex_8 = _ex_8;
133
134 // static numeric -7
135 const numeric *_num_7_p;
136 const ex _ex_7 = _ex_7;
137
138 // static numeric -6
139 const numeric *_num_6_p;
140 const ex _ex_6 = _ex_6;
141
142 // static numeric -5
143 const numeric *_num_5_p;
144 const ex _ex_5 = _ex_5;
145
146 // static numeric -4
147 const numeric *_num_4_p;
148 const ex _ex_4 = _ex_4;
149
150 // static numeric -3
151 const numeric *_num_3_p;
152 const ex _ex_3 = _ex_3;
153
154 // static numeric -2
155 const numeric *_num_2_p;
156 const ex _ex_2 = _ex_2;
157
158 // static numeric -1
159 const numeric *_num_1_p;
160 const ex _ex_1 = _ex_1;
161
162 // static numeric -1/2
163 const numeric *_num_1_2_p;
164 const ex _ex_1_2= _ex_1_2;
165
166 // static numeric -1/3
167 const numeric *_num_1_3_p;
168 const ex _ex_1_3= _ex_1_3;
169
170 // static numeric -1/4
171 const numeric *_num_1_4_p;
172 const ex _ex_1_4= _ex_1_4;
173
174 // static numeric 0
175 const numeric *_num0_p;
176 const basic *_num0_bp;
177 const ex _ex0 = _ex0;
178
179 // static numeric 1/4
180 const numeric *_num1_4_p;
181 const ex _ex1_4 = _ex1_4;
182
183 // static numeric 1/3
184 const numeric *_num1_3_p;
185 const ex _ex1_3 = _ex1_3;
186
187 // static numeric 1/2
188 const numeric *_num1_2_p;
189 const ex _ex1_2 = _ex1_2;
190
191 // static numeric 1
192 const numeric *_num1_p;
193 const ex _ex1 = _ex1;
194
195 // static numeric 2
196 const numeric *_num2_p;
197 const ex _ex2 = _ex2;
198
199 // static numeric 3
200 const numeric *_num3_p;
201 const ex _ex3 = _ex3;
202
203 // static numeric 4
204 const numeric *_num4_p;
205 const ex _ex4 = _ex4;
206
207 // static numeric 5
208 const numeric *_num5_p;
209 const ex _ex5 = _ex5;
210
211 // static numeric 6
212 const numeric *_num6_p;
213 const ex _ex6 = _ex6;
214
215 // static numeric 7
216 const numeric *_num7_p;
217 const ex _ex7 = _ex7;
218
219 // static numeric 8
220 const numeric *_num8_p;
221 const ex _ex8 = _ex8;
222
223 // static numeric 9
224 const numeric *_num9_p;
225 const ex _ex9 = _ex9;
226
227 // static numeric 10
228 const numeric *_num10_p;
229 const ex _ex10 = _ex10;
230
231 // static numeric 11
232 const numeric *_num11_p;
233 const ex _ex11 = _ex11;
234
235 // static numeric 12
236 const numeric *_num12_p;
237 const ex _ex12 = _ex12;
238
239 // static numeric 15
240 const numeric *_num15_p;
241 const ex _ex15 = _ex15;
242
243 // static numeric 18
244 const numeric *_num18_p;
245 const ex _ex18 = _ex18;
246
247 // static numeric 20
248 const numeric *_num20_p;
249 const ex _ex20 = _ex20;
250
251 // static numeric 24
252 const numeric *_num24_p;
253 const ex _ex24 = _ex24;
254
255 // static numeric 25
256 const numeric *_num25_p;
257 const ex _ex25 = _ex25;
258
259 // static numeric 30
260 const numeric *_num30_p;
261 const ex _ex30 = _ex30;
262
263 // static numeric 48
264 const numeric *_num48_p;
265 const ex _ex48 = _ex48;
266
267 // static numeric 60
268 const numeric *_num60_p;
269 const ex _ex60 = _ex60;
270
271 // static numeric 120
272 const numeric *_num120_p;
273 const ex _ex120 = _ex120;
274
275 /** Ctor of static initialization helpers.  The fist call to this is going
276  *  to initialize the library, the others do nothing. */
277 library_init::library_init()
278 {
279         if (count++==0) {
280                 _num_120_p = (const numeric *)&dynallocate<numeric>(-120);
281                 _num_60_p = (const numeric *)&dynallocate<numeric>(-60);
282                 _num_48_p = (const numeric *)&dynallocate<numeric>(-48);
283                 _num_30_p = (const numeric *)&dynallocate<numeric>(-30);
284                 _num_25_p = (const numeric *)&dynallocate<numeric>(-25);
285                 _num_24_p = (const numeric *)&dynallocate<numeric>(-24);
286                 _num_20_p = (const numeric *)&dynallocate<numeric>(-20);
287                 _num_18_p = (const numeric *)&dynallocate<numeric>(-18);
288                 _num_15_p = (const numeric *)&dynallocate<numeric>(-15);
289                 _num_12_p = (const numeric *)&dynallocate<numeric>(-12);
290                 _num_11_p = (const numeric *)&dynallocate<numeric>(-11);
291                 _num_10_p = (const numeric *)&dynallocate<numeric>(-10);
292                 _num_9_p = (const numeric *)&dynallocate<numeric>(-9);
293                 _num_8_p = (const numeric *)&dynallocate<numeric>(-8);
294                 _num_7_p = (const numeric *)&dynallocate<numeric>(-7);
295                 _num_6_p = (const numeric *)&dynallocate<numeric>(-6);
296                 _num_5_p = (const numeric *)&dynallocate<numeric>(-5);
297                 _num_4_p = (const numeric *)&dynallocate<numeric>(-4);
298                 _num_3_p = (const numeric *)&dynallocate<numeric>(-3);
299                 _num_2_p = (const numeric *)&dynallocate<numeric>(-2);
300                 _num_1_p = (const numeric *)&dynallocate<numeric>(-1);
301                 _num_1_2_p = (const numeric *)&dynallocate<numeric>(-1,2);
302                 _num_1_3_p = (const numeric *)&dynallocate<numeric>(-1,3);
303                 _num_1_4_p = (const numeric *)&dynallocate<numeric>(-1,4);
304                 _num0_p = (const numeric *)&dynallocate<numeric>(0);
305                 _num0_bp  = _num0_p;  // Cf. class ex default ctor.
306                 _num1_4_p = (const numeric *)&dynallocate<numeric>(1,4);
307                 _num1_3_p = (const numeric *)&dynallocate<numeric>(1,3);
308                 _num1_2_p = (const numeric *)&dynallocate<numeric>(1,2);
309                 _num1_p = (const numeric *)&dynallocate<numeric>(1);
310                 _num2_p = (const numeric *)&dynallocate<numeric>(2);
311                 _num3_p = (const numeric *)&dynallocate<numeric>(3);
312                 _num4_p = (const numeric *)&dynallocate<numeric>(4);
313                 _num5_p = (const numeric *)&dynallocate<numeric>(5);
314                 _num6_p = (const numeric *)&dynallocate<numeric>(6);
315                 _num7_p = (const numeric *)&dynallocate<numeric>(7);
316                 _num8_p = (const numeric *)&dynallocate<numeric>(8);
317                 _num9_p = (const numeric *)&dynallocate<numeric>(9);
318                 _num10_p = (const numeric *)&dynallocate<numeric>(10);
319                 _num11_p = (const numeric *)&dynallocate<numeric>(11);
320                 _num12_p = (const numeric *)&dynallocate<numeric>(12);
321                 _num15_p = (const numeric *)&dynallocate<numeric>(15);
322                 _num18_p = (const numeric *)&dynallocate<numeric>(18);
323                 _num20_p = (const numeric *)&dynallocate<numeric>(20);
324                 _num24_p = (const numeric *)&dynallocate<numeric>(24);
325                 _num25_p = (const numeric *)&dynallocate<numeric>(25);
326                 _num30_p = (const numeric *)&dynallocate<numeric>(30);
327                 _num48_p = (const numeric *)&dynallocate<numeric>(48);
328                 _num60_p = (const numeric *)&dynallocate<numeric>(60);
329                 _num120_p = (const numeric *)&dynallocate<numeric>(120);
330
331                 new((void*)&_ex_120) ex(*_num_120_p);
332                 new((void*)&_ex_60) ex(*_num_60_p);
333                 new((void*)&_ex_48) ex(*_num_48_p);
334                 new((void*)&_ex_30) ex(*_num_30_p);
335                 new((void*)&_ex_25) ex(*_num_25_p);
336                 new((void*)&_ex_24) ex(*_num_24_p);
337                 new((void*)&_ex_20) ex(*_num_20_p);
338                 new((void*)&_ex_18) ex(*_num_18_p);
339                 new((void*)&_ex_15) ex(*_num_15_p);
340                 new((void*)&_ex_12) ex(*_num_12_p);
341                 new((void*)&_ex_11) ex(*_num_11_p);
342                 new((void*)&_ex_10) ex(*_num_10_p);
343                 new((void*)&_ex_9) ex(*_num_9_p);
344                 new((void*)&_ex_8) ex(*_num_8_p);
345                 new((void*)&_ex_7) ex(*_num_7_p);
346                 new((void*)&_ex_6) ex(*_num_6_p);
347                 new((void*)&_ex_5) ex(*_num_5_p);
348                 new((void*)&_ex_4) ex(*_num_4_p);
349                 new((void*)&_ex_3) ex(*_num_3_p);
350                 new((void*)&_ex_2) ex(*_num_2_p);
351                 new((void*)&_ex_1) ex(*_num_1_p);
352                 new((void*)&_ex_1_2) ex(*_num_1_2_p);
353                 new((void*)&_ex_1_3) ex(*_num_1_3_p);
354                 new((void*)&_ex_1_4) ex(*_num_1_4_p);
355                 new((void*)&_ex0) ex(*_num0_p);
356                 new((void*)&_ex1_4) ex(*_num1_4_p);
357                 new((void*)&_ex1_3) ex(*_num1_3_p);
358                 new((void*)&_ex1_2) ex(*_num1_2_p);
359                 new((void*)&_ex1) ex(*_num1_p);
360                 new((void*)&_ex2) ex(*_num2_p);
361                 new((void*)&_ex3) ex(*_num3_p);
362                 new((void*)&_ex4) ex(*_num4_p);
363                 new((void*)&_ex5) ex(*_num5_p);
364                 new((void*)&_ex6) ex(*_num6_p);
365                 new((void*)&_ex7) ex(*_num7_p);
366                 new((void*)&_ex8) ex(*_num8_p);
367                 new((void*)&_ex9) ex(*_num9_p);
368                 new((void*)&_ex10) ex(*_num10_p);
369                 new((void*)&_ex11) ex(*_num11_p);
370                 new((void*)&_ex12) ex(*_num12_p);
371                 new((void*)&_ex15) ex(*_num15_p);
372                 new((void*)&_ex18) ex(*_num18_p);
373                 new((void*)&_ex20) ex(*_num20_p);
374                 new((void*)&_ex24) ex(*_num24_p);
375                 new((void*)&_ex25) ex(*_num25_p);
376                 new((void*)&_ex30) ex(*_num30_p);
377                 new((void*)&_ex48) ex(*_num48_p);
378                 new((void*)&_ex60) ex(*_num60_p);
379                 new((void*)&_ex120) ex(*_num120_p);
380
381                 // Initialize print context class info (this is not strictly necessary
382                 // but we do it anyway to make print_context_class_info::dump_hierarchy()
383                 // output the whole hierarchy whether or not the classes are actually
384                 // used)
385                 print_context::get_class_info_static();
386                 print_dflt::get_class_info_static();
387                 print_latex::get_class_info_static();
388                 print_python::get_class_info_static();
389                 print_python_repr::get_class_info_static();
390                 print_tree::get_class_info_static();
391                 print_csrc::get_class_info_static();
392                 print_csrc_float::get_class_info_static();
393                 print_csrc_double::get_class_info_static();
394                 print_csrc_cl_N::get_class_info_static();
395         }
396 }
397
398
399 /** Dtor of static initialization helpers.  The last call to this is going
400  *  to shut down the library, the others do nothing. */
401 library_init::~library_init()
402 {
403         if (--count==0) {
404                 // It's really necessary to clean up, since the program
405                 // lifetime might not be the same as libginac.{so,dll} one
406                 // (e.g. consider // dlopen/dlsym/dlclose sequence).
407                 // Let the ex dtors care for deleting the numerics!
408                 _ex120.~ex();
409                 _ex_120.~ex();
410                 _ex60.~ex();
411                 _ex_60.~ex();
412                 _ex48.~ex();
413                 _ex_48.~ex();
414                 _ex30.~ex();
415                 _ex_30.~ex();
416                 _ex25.~ex();
417                 _ex_25.~ex();
418                 _ex24.~ex();
419                 _ex_24.~ex();
420                 _ex20.~ex();
421                 _ex_20.~ex();
422                 _ex18.~ex();
423                 _ex_18.~ex();
424                 _ex15.~ex();
425                 _ex_15.~ex();
426                 _ex12.~ex();
427                 _ex_12.~ex();
428                 _ex11.~ex();
429                 _ex_11.~ex();
430                 _ex10.~ex();
431                 _ex_10.~ex();
432                 _ex9.~ex();
433                 _ex_9.~ex();
434                 _ex8.~ex();
435                 _ex_8.~ex();
436                 _ex7.~ex();
437                 _ex_7.~ex();
438                 _ex6.~ex();
439                 _ex_6.~ex();
440                 _ex5.~ex();
441                 _ex_5.~ex();
442                 _ex4.~ex();
443                 _ex_4.~ex();
444                 _ex3.~ex();
445                 _ex_3.~ex();
446                 _ex2.~ex();
447                 _ex_2.~ex();
448                 _ex1.~ex();
449                 _ex_1.~ex();
450                 _ex1_2.~ex();
451                 _ex_1_2.~ex();
452                 _ex1_3.~ex();
453                 _ex_1_3.~ex();
454                 _ex1_4.~ex();
455                 _ex_1_4.~ex();
456                 _ex0.~ex();
457         }
458 }
459
460 void library_init::init_unarchivers() { }
461
462 // comment skeleton for header files
463
464
465 // member functions
466
467         // default constructor, destructor, copy constructor and assignment operator
468         // none
469
470         // other constructors
471         // none
472
473         // functions overriding virtual functions from base classes
474         // none
475         
476         // new virtual functions which can be overridden by derived classes
477         // none
478
479         // non-virtual functions in this class
480         // none
481
482 // member variables
483 // none
484         
485
486
487 // comment skeleton for implementation files
488
489
490 //////////
491 // default constructor, destructor, copy constructor and assignment operator
492 //////////
493
494 // public
495 // protected
496
497 //////////
498 // other constructors
499 //////////
500
501 // public
502 // none
503
504 //////////
505 // functions overriding virtual functions from base classes
506 //////////
507
508 // public
509 // protected
510 // none
511
512 //////////
513 // new virtual functions which can be overridden by derived classes
514 //////////
515
516 // public
517 // protected
518 // none
519
520 //////////
521 // non-virtual functions in this class
522 //////////
523
524 // public
525 // protected
526 // none
527
528 //////////
529 // static member variables
530 //////////
531
532 // protected
533 // private
534 // none
535
536
537 } // namespace GiNaC