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