3 * Implementation of several small and furry utilities needed within GiNaC
4 * but not of any interest to the user of the library. */
7 * GiNaC Copyright (C) 1999-2017 Johannes Gutenberg University Mainz, Germany
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.
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.
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
26 #include "operators.h"
32 /* Version information buried into the library */
33 const int version_major = GINACLIB_MAJOR_VERSION;
34 const int version_minor = GINACLIB_MINOR_VERSION;
35 const int version_micro = GINACLIB_MICRO_VERSION;
38 /** ctor for pole_error exception class. */
39 pole_error::pole_error(const std::string& what_arg, int degree)
40 : domain_error(what_arg), deg(degree) { }
42 /** Return the degree of the pole_error exception class. */
43 int pole_error::degree() const
48 /** Integer binary logarithm */
49 unsigned log2(unsigned n)
52 for (k = 0; n > 1; n >>= 1)
57 /** Compute the multinomial coefficient n!/(p1!*p2!*...*pk!) where
58 * n = p1+p2+...+pk, i.e. p is a partition of n.
61 multinomial_coefficient(const std::vector<int> & p)
66 d *= factorial(numeric(it));
68 return factorial(n) / d;
72 // flyweight chest of numbers is initialized here:
75 /** How many static objects were created? Only the first one must create
76 * the static flyweights on the heap. */
77 int library_init::count = 0;
79 // static numeric -120
80 const numeric *_num_120_p;
81 const ex _ex_120 = _ex_120;
84 const numeric *_num_60_p;
85 const ex _ex_60 = _ex_60;
88 const numeric *_num_48_p;
89 const ex _ex_48 = _ex_48;
92 const numeric *_num_30_p;
93 const ex _ex_30 = _ex_30;
96 const numeric *_num_25_p;
97 const ex _ex_25 = _ex_25;
100 const numeric *_num_24_p;
101 const ex _ex_24 = _ex_24;
103 // static numeric -20
104 const numeric *_num_20_p;
105 const ex _ex_20 = _ex_20;
107 // static numeric -18
108 const numeric *_num_18_p;
109 const ex _ex_18 = _ex_18;
111 // static numeric -15
112 const numeric *_num_15_p;
113 const ex _ex_15 = _ex_15;
115 // static numeric -12
116 const numeric *_num_12_p;
117 const ex _ex_12 = _ex_12;
119 // static numeric -11
120 const numeric *_num_11_p;
121 const ex _ex_11 = _ex_11;
123 // static numeric -10
124 const numeric *_num_10_p;
125 const ex _ex_10 = _ex_10;
128 const numeric *_num_9_p;
129 const ex _ex_9 = _ex_9;
132 const numeric *_num_8_p;
133 const ex _ex_8 = _ex_8;
136 const numeric *_num_7_p;
137 const ex _ex_7 = _ex_7;
140 const numeric *_num_6_p;
141 const ex _ex_6 = _ex_6;
144 const numeric *_num_5_p;
145 const ex _ex_5 = _ex_5;
148 const numeric *_num_4_p;
149 const ex _ex_4 = _ex_4;
152 const numeric *_num_3_p;
153 const ex _ex_3 = _ex_3;
156 const numeric *_num_2_p;
157 const ex _ex_2 = _ex_2;
160 const numeric *_num_1_p;
161 const ex _ex_1 = _ex_1;
163 // static numeric -1/2
164 const numeric *_num_1_2_p;
165 const ex _ex_1_2= _ex_1_2;
167 // static numeric -1/3
168 const numeric *_num_1_3_p;
169 const ex _ex_1_3= _ex_1_3;
171 // static numeric -1/4
172 const numeric *_num_1_4_p;
173 const ex _ex_1_4= _ex_1_4;
176 const numeric *_num0_p;
177 const basic *_num0_bp;
178 const ex _ex0 = _ex0;
180 // static numeric 1/4
181 const numeric *_num1_4_p;
182 const ex _ex1_4 = _ex1_4;
184 // static numeric 1/3
185 const numeric *_num1_3_p;
186 const ex _ex1_3 = _ex1_3;
188 // static numeric 1/2
189 const numeric *_num1_2_p;
190 const ex _ex1_2 = _ex1_2;
193 const numeric *_num1_p;
194 const ex _ex1 = _ex1;
197 const numeric *_num2_p;
198 const ex _ex2 = _ex2;
201 const numeric *_num3_p;
202 const ex _ex3 = _ex3;
205 const numeric *_num4_p;
206 const ex _ex4 = _ex4;
209 const numeric *_num5_p;
210 const ex _ex5 = _ex5;
213 const numeric *_num6_p;
214 const ex _ex6 = _ex6;
217 const numeric *_num7_p;
218 const ex _ex7 = _ex7;
221 const numeric *_num8_p;
222 const ex _ex8 = _ex8;
225 const numeric *_num9_p;
226 const ex _ex9 = _ex9;
229 const numeric *_num10_p;
230 const ex _ex10 = _ex10;
233 const numeric *_num11_p;
234 const ex _ex11 = _ex11;
237 const numeric *_num12_p;
238 const ex _ex12 = _ex12;
241 const numeric *_num15_p;
242 const ex _ex15 = _ex15;
245 const numeric *_num18_p;
246 const ex _ex18 = _ex18;
249 const numeric *_num20_p;
250 const ex _ex20 = _ex20;
253 const numeric *_num24_p;
254 const ex _ex24 = _ex24;
257 const numeric *_num25_p;
258 const ex _ex25 = _ex25;
261 const numeric *_num30_p;
262 const ex _ex30 = _ex30;
265 const numeric *_num48_p;
266 const ex _ex48 = _ex48;
269 const numeric *_num60_p;
270 const ex _ex60 = _ex60;
272 // static numeric 120
273 const numeric *_num120_p;
274 const ex _ex120 = _ex120;
276 /** Ctor of static initialization helpers. The fist call to this is going
277 * to initialize the library, the others do nothing. */
278 library_init::library_init()
281 _num_120_p = (const numeric *)&dynallocate<numeric>(-120);
282 _num_60_p = (const numeric *)&dynallocate<numeric>(-60);
283 _num_48_p = (const numeric *)&dynallocate<numeric>(-48);
284 _num_30_p = (const numeric *)&dynallocate<numeric>(-30);
285 _num_25_p = (const numeric *)&dynallocate<numeric>(-25);
286 _num_24_p = (const numeric *)&dynallocate<numeric>(-24);
287 _num_20_p = (const numeric *)&dynallocate<numeric>(-20);
288 _num_18_p = (const numeric *)&dynallocate<numeric>(-18);
289 _num_15_p = (const numeric *)&dynallocate<numeric>(-15);
290 _num_12_p = (const numeric *)&dynallocate<numeric>(-12);
291 _num_11_p = (const numeric *)&dynallocate<numeric>(-11);
292 _num_10_p = (const numeric *)&dynallocate<numeric>(-10);
293 _num_9_p = (const numeric *)&dynallocate<numeric>(-9);
294 _num_8_p = (const numeric *)&dynallocate<numeric>(-8);
295 _num_7_p = (const numeric *)&dynallocate<numeric>(-7);
296 _num_6_p = (const numeric *)&dynallocate<numeric>(-6);
297 _num_5_p = (const numeric *)&dynallocate<numeric>(-5);
298 _num_4_p = (const numeric *)&dynallocate<numeric>(-4);
299 _num_3_p = (const numeric *)&dynallocate<numeric>(-3);
300 _num_2_p = (const numeric *)&dynallocate<numeric>(-2);
301 _num_1_p = (const numeric *)&dynallocate<numeric>(-1);
302 _num_1_2_p = (const numeric *)&dynallocate<numeric>(-1,2);
303 _num_1_3_p = (const numeric *)&dynallocate<numeric>(-1,3);
304 _num_1_4_p = (const numeric *)&dynallocate<numeric>(-1,4);
305 _num0_p = (const numeric *)&dynallocate<numeric>(0);
306 _num0_bp = _num0_p; // Cf. class ex default ctor.
307 _num1_4_p = (const numeric *)&dynallocate<numeric>(1,4);
308 _num1_3_p = (const numeric *)&dynallocate<numeric>(1,3);
309 _num1_2_p = (const numeric *)&dynallocate<numeric>(1,2);
310 _num1_p = (const numeric *)&dynallocate<numeric>(1);
311 _num2_p = (const numeric *)&dynallocate<numeric>(2);
312 _num3_p = (const numeric *)&dynallocate<numeric>(3);
313 _num4_p = (const numeric *)&dynallocate<numeric>(4);
314 _num5_p = (const numeric *)&dynallocate<numeric>(5);
315 _num6_p = (const numeric *)&dynallocate<numeric>(6);
316 _num7_p = (const numeric *)&dynallocate<numeric>(7);
317 _num8_p = (const numeric *)&dynallocate<numeric>(8);
318 _num9_p = (const numeric *)&dynallocate<numeric>(9);
319 _num10_p = (const numeric *)&dynallocate<numeric>(10);
320 _num11_p = (const numeric *)&dynallocate<numeric>(11);
321 _num12_p = (const numeric *)&dynallocate<numeric>(12);
322 _num15_p = (const numeric *)&dynallocate<numeric>(15);
323 _num18_p = (const numeric *)&dynallocate<numeric>(18);
324 _num20_p = (const numeric *)&dynallocate<numeric>(20);
325 _num24_p = (const numeric *)&dynallocate<numeric>(24);
326 _num25_p = (const numeric *)&dynallocate<numeric>(25);
327 _num30_p = (const numeric *)&dynallocate<numeric>(30);
328 _num48_p = (const numeric *)&dynallocate<numeric>(48);
329 _num60_p = (const numeric *)&dynallocate<numeric>(60);
330 _num120_p = (const numeric *)&dynallocate<numeric>(120);
332 new((void*)&_ex_120) ex(*_num_120_p);
333 new((void*)&_ex_60) ex(*_num_60_p);
334 new((void*)&_ex_48) ex(*_num_48_p);
335 new((void*)&_ex_30) ex(*_num_30_p);
336 new((void*)&_ex_25) ex(*_num_25_p);
337 new((void*)&_ex_24) ex(*_num_24_p);
338 new((void*)&_ex_20) ex(*_num_20_p);
339 new((void*)&_ex_18) ex(*_num_18_p);
340 new((void*)&_ex_15) ex(*_num_15_p);
341 new((void*)&_ex_12) ex(*_num_12_p);
342 new((void*)&_ex_11) ex(*_num_11_p);
343 new((void*)&_ex_10) ex(*_num_10_p);
344 new((void*)&_ex_9) ex(*_num_9_p);
345 new((void*)&_ex_8) ex(*_num_8_p);
346 new((void*)&_ex_7) ex(*_num_7_p);
347 new((void*)&_ex_6) ex(*_num_6_p);
348 new((void*)&_ex_5) ex(*_num_5_p);
349 new((void*)&_ex_4) ex(*_num_4_p);
350 new((void*)&_ex_3) ex(*_num_3_p);
351 new((void*)&_ex_2) ex(*_num_2_p);
352 new((void*)&_ex_1) ex(*_num_1_p);
353 new((void*)&_ex_1_2) ex(*_num_1_2_p);
354 new((void*)&_ex_1_3) ex(*_num_1_3_p);
355 new((void*)&_ex_1_4) ex(*_num_1_4_p);
356 new((void*)&_ex0) ex(*_num0_p);
357 new((void*)&_ex1_4) ex(*_num1_4_p);
358 new((void*)&_ex1_3) ex(*_num1_3_p);
359 new((void*)&_ex1_2) ex(*_num1_2_p);
360 new((void*)&_ex1) ex(*_num1_p);
361 new((void*)&_ex2) ex(*_num2_p);
362 new((void*)&_ex3) ex(*_num3_p);
363 new((void*)&_ex4) ex(*_num4_p);
364 new((void*)&_ex5) ex(*_num5_p);
365 new((void*)&_ex6) ex(*_num6_p);
366 new((void*)&_ex7) ex(*_num7_p);
367 new((void*)&_ex8) ex(*_num8_p);
368 new((void*)&_ex9) ex(*_num9_p);
369 new((void*)&_ex10) ex(*_num10_p);
370 new((void*)&_ex11) ex(*_num11_p);
371 new((void*)&_ex12) ex(*_num12_p);
372 new((void*)&_ex15) ex(*_num15_p);
373 new((void*)&_ex18) ex(*_num18_p);
374 new((void*)&_ex20) ex(*_num20_p);
375 new((void*)&_ex24) ex(*_num24_p);
376 new((void*)&_ex25) ex(*_num25_p);
377 new((void*)&_ex30) ex(*_num30_p);
378 new((void*)&_ex48) ex(*_num48_p);
379 new((void*)&_ex60) ex(*_num60_p);
380 new((void*)&_ex120) ex(*_num120_p);
382 // Initialize print context class info (this is not strictly necessary
383 // but we do it anyway to make print_context_class_info::dump_hierarchy()
384 // output the whole hierarchy whether or not the classes are actually
386 print_context::get_class_info_static();
387 print_dflt::get_class_info_static();
388 print_latex::get_class_info_static();
389 print_python::get_class_info_static();
390 print_python_repr::get_class_info_static();
391 print_tree::get_class_info_static();
392 print_csrc::get_class_info_static();
393 print_csrc_float::get_class_info_static();
394 print_csrc_double::get_class_info_static();
395 print_csrc_cl_N::get_class_info_static();
400 /** Dtor of static initialization helpers. The last call to this is going
401 * to shut down the library, the others do nothing. */
402 library_init::~library_init()
405 // It's really necessary to clean up, since the program
406 // lifetime might not be the same as libginac.{so,dll} one
407 // (e.g. consider // dlopen/dlsym/dlclose sequence).
408 // Let the ex dtors care for deleting the numerics!
461 void library_init::init_unarchivers() { }
463 // comment skeleton for header files
468 // default constructor, destructor, copy constructor and assignment operator
471 // other constructors
474 // functions overriding virtual functions from base classes
477 // new virtual functions which can be overridden by derived classes
480 // non-virtual functions in this class
488 // comment skeleton for implementation files
492 // default constructor, destructor, copy constructor and assignment operator
499 // other constructors
506 // functions overriding virtual functions from base classes
514 // new virtual functions which can be overridden by derived classes
522 // non-virtual functions in this class
530 // static member variables