piranha  0.10
piranha.hpp
Go to the documentation of this file.
1 /* Copyright 2009-2017 Francesco Biscani (bluescarni@gmail.com)
2 
3 This file is part of the Piranha library.
4 
5 The Piranha library is free software; you can redistribute it and/or modify
6 it under the terms of either:
7 
8  * the GNU Lesser General Public License as published by the Free
9  Software Foundation; either version 3 of the License, or (at your
10  option) any later version.
11 
12 or
13 
14  * the GNU General Public License as published by the Free Software
15  Foundation; either version 3 of the License, or (at your option) any
16  later version.
17 
18 or both in parallel, as here.
19 
20 The Piranha library is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 for more details.
24 
25 You should have received copies of the GNU General Public License and the
26 GNU Lesser General Public License along with the Piranha library. If not,
27 see https://www.gnu.org/licenses/. */
28 
29 #ifndef PIRANHA_PIRANHA_HPP
30 #define PIRANHA_PIRANHA_HPP
31 
38 /*
40  * \todo explain in general section the base assumptions of move semantics and thread safety (e.g., require implicitly
41  * that
42  * all moved-from objects are assignable and destructable, and everything not thread-safe by default).
43  * \todo base_series test: missing merge terms with negative+move (that actually swaps the contents of the series) and
44  * negative+move with different series types.
45  * \todo check usage of max_load_factor (especially wrt flukes in * instead of / or viceversa).
46  * \todo review use of numeric_cast: in some places we might be using it in such a way we expect errors if converting
47  * floating point to int, but this is not the case (from the doc)
48  * \todo the tuning parameters should be tested and justified (e.g., when to go into mt mode, etc.).
49  * \todo series multadd to speed-up series multiplication when coefficients are series?
50  * \todo look into perfect forwarding of members, for use in series, hash set (?)
51  * http://stackoverflow.com/questions/8570655/perfect-forwarding-a-member-of-object
52  * update: tried this on the series insertion methods, it seems like GCC does not implement this correctly (while clang
53  * does). Check again in the future.
54  * \todo it seems like default construction of c++ containers might throw :/ We should probably double-check we do not
55  * assume any nothrow behaviour in
56  * such cases. For instance, if we use an old-style C allocation function and we need to create a container _before_
57  * calling free(), then the behaviour
58  * might not be exception-safe.
59  * \todo in pyranha, access to static variables should be made thread-safe (first of all in the Python sense,
60  * e.g., importing the module from multiple Python threads).
61  * \todo pyranha: enable math for numpy's floating point type, and arrays. Also, think about enabling conversion from
62  * the numpy float
63  * in the from-python converters? -> if we do this last bit, we must make sure that our custom converter does not
64  * override any other
65  * converter that might be registered in boost python. We need to query the registry and check at runtime.
66  * \todo after the switch to 4.8, we can drop in many places the forward ctor macro in favour of just inheriting
67  * constructors (in other
68  * places, e.g., polynomial, we still need them as we are adding new custom ctors). Probably the assignment macro must
69  * stay anyway.
70  * update: tried this for a while, it looks like the semantics of inheriting ctors might not be what we need, and the
71  * support in compilers
72  * is still brittle. Maybe revisit in the future.
73  * \todo consider replacing the & operator with std::addressof in positional new forms. It seems there might be a perf.
74  * penalty
75  * involved in doing that, if that is the case we can either do it only if the type is not POD or maybe even if it does
76  * not have
77  * the operator overloaded (via decltype SFINAE).
78  * \todo in pyranha, we should be able to provide self-descriptive docstrings for the exposed series, based on the
79  * template enable_if mechanism.
80  * \todo consider bringing back the unroller from the vectorization work into the small_vector class.
81  * \todo some versions of mingw want __mingw_aligned_malloc instead of _aligned_malloc, fix this with a check in the
82  * build system. Or
83  * maybe check whether __mingw_aligned_malloc is available in all mingw versions.
84  * \todo check usages of std algorithms against the assumptions on the functors used:
85  * http://stackoverflow.com/questions/20119810/parallel-implementations-of-std-algorithms-and-side-effects
86  * \todo review all usages of lexical_cast and stringstreams, probably we need either to replace them altogether or at
87  * least to make
88  * sure they behave consistently wrt locale settings. UPDATE: we can actually switch to std::to_string() in many cases,
89  * and keep lexical_cast only for the conversion of piranha's types to string. UPDATE: it looks like to_string is
90  * influenced by the locale setting, it's probably better to roll our implementation.
91  * \todo doxygen: check usage of param[(in,)out], and consider using the tparam command.
92  * \todo review the use of return statements with const objects, if any.
93  * \todo math::is_zero() is used to determine ignorability of a term in a noexcept method in term. Should we require it
94  * to be
95  * noexcept as well and put the requirement in the is_cf type trait?
96  * \todo floating point stuff: there's a few things we can improve here. The first problem is that, in some places where
97  * it could
98  * matter (interop mp_integer/rational <--> float) we don't check for math errors, as explained here:
99  * http://en.cppreference.com/w/cpp/numeric/math/math_errhandling
100  * We should probably check for errors when we need things to be exact and safe. These include ilogb, scalb, trunc, etc.
101  * Secondly,
102  * we have a bunch of generic fp algorithms that could be easily extended to work with nonstandard fp types such as
103  * quadmath
104  * and decimal. We need then to abstract fp standard functions in our own wrappers and abstract away in a separate place
105  * our
106  * generic algos scattered around. Then in the wrappers we could add automatic checks for errno (raise exception) and
107  * kill two
108  * birds with one stone.
109  * \todo review the usage of _fwd headers. It seems it is ok for friend declarations for instance, but wherever we might
110  * need the full definition of the object we might want to reorganise the code.
111  * \todo the prepare_for_print() should probably become a public print_exponent(), that also takes care of putting
112  * brackets
113  * e.g. when printing rational exponents with non-unitary denominator.
114  * \todo probably we should change the pow() implementation for integer to error out if the power is negative and the
115  * base
116  * is not unitary.
117  * \todo in pyranha, it would be nice to have a reverse lookup from the name of the exposed types to their
118  * representation
119  * in the type system. Plus, maybe when printing the series they should have a header displaying their name in the type
120  * system and maybe the list of arguments. Also, what happens if we expose, say, polynomial<double> *and*
121  * polynomial<double,k_monomial>,
122  * supposing that they are the same type one day?
123  * \todo should the print coefficient operator of real print the precision as well or is the number of digits enough
124  * hint?
125  * \todo need to review the requirements on all std object we use as members of classes. We often require them to be
126  * noexcept
127  * but they do not need to be by the standard (e.g., hash, equal_to, vector, ...). Note that in all our classes we mark
128  * move
129  * operations as noexcept so we don't really need to require std members to be noexcept (if they throw an exception -
130  * unlikely
131  * - the program will terminate anyway). We should also probably check the uses of std::move in order to make sure we do
132  * not use
133  * exception guarantees throughout the code.
134  * \todo do the noexcept methods in keys really need to be noexcept? Maybe it is better to offer a weaker exception
135  * guarantee
136  * and be done with them instead.
137  * \todo there could be some tension between SFINAE and the hard errors from static asserts in certain type traits such
138  * as key_is_*,
139  * series_is_*, etc. So far this has resulted in no practical problems, but in the future we might want to look again at
140  * this.
141  * UPDATE: this came up and was solved in series_is_rebindable by replacing the hard assertion errors with simply
142  * setting the value
143  * of the type trait to false via a specialisation. Keep this solution in mind if the problem arises elsewhere.
144  * \todo serialization: it seems like if the text in the archive is complete garbage, the destructor will throw. Check
145  * that this behaviour
146  * is ok in Python, and that the exception from boost serialization is thrown and translated properly. Maybe test
147  * garbage archives
148  * also in the existing serialization tests.
149  * \todo positional new needs the <new> header.
150  * \todo std::move() needs the <utility> header.
151  * \todo as an idea, the series specialisations for the impl functors in the toolboxes might all go in series.hpp, with
152  * the following conditions:
153  * - the involved object is/are series,
154  * - they support the needed methods (e.g., subs(), degree(), etc.).
155  * This way if we need, e.g., a custom subs() in a particular series type, we can implement the custom method (i.e.,
156  * without using the toolbox) but still ending
157  * up with a correct math::subs() specialisation without having to re-code it for the particular series type. We need to
158  * check that we always use
159  * math::* functors instead of member functions in order to avoid picking the base implementation.
160  * \todo related to the above, beautification of the enabling conditions for impl functors - in the same fashion as we
161  * do for methods and functions.
162  * \todo we probably need a way to handle the excessive growth of ipow caches. Just keep the most recently used entries
163  * up to a certain
164  * user-configurable limit. Also, it might be useful to give the user the ability to query the cache, see how many items
165  * are stored, etc.
166  * \todo we should really add some perf tests based on the work by alex perminov. Also, based on this, which operations
167  * in his use cases could
168  * benefit from parallelisation?
169  * \todo the replace_symbol() method for series. Or maybe rename_symbol().
170  * \todo get rid of the global state for the symbols, just store strings. This should allow to remove the ugliness of
171  * checking the shutdown flag.
172  * \todo consider the use of the upcoming std::shared_lock/mutex for multiple readers/single writer situations (e.g., in
173  * the custom derivative
174  * machinery). Maybe we can do with the boost counterpart if it does not require extra linking, until C++14.
175  * \todo it looks like in many cases we can hide excess default template parameters used in TMP by adding an extra layer
176  * of indirection. This has only cosmetic
177  * value, but might be worth for clarity in the long run.
178  * \todo the pattern of sin/cos in poisson series and invert in divisor_series (that is, recurse until a polynomial
179  * coefficient is found) should probably
180  * be applied in the integration routine for poisson series that integrates by part when coefficient has positive degree
181  * in the integration variable
182  * and the trig part also depend on the integration variable.
183  * \todo related to the above: we should probably generalise the integral_combination() in polynomial to deal also with
184  * recursively-represented polys,
185  * so that, e.g., we can use them as coefficients in poisson series. Also the polynomial's special pow() and integrate()
186  * method should be able to deal
187  * with recursive polys in the same fashion. This should probably be a bullet point if we ever decide to support
188  * recrusive polynomials as first-class citizens.
189  * \todo the tuning:: class should probably be rolled into settings.
190  * \todo think about removing the noexcept requirements for ignorability and compatibility of terms. This makes sense
191  * logically as ignorability is anyway
192  * gonna call is_zero(), which might throw (see bp_object for instance), we might end up simplifying the logic and we
193  * don't lose much (not a big deal
194  * if the exception safety is weaker). If we do this, we need to check all usages of is_ignorable()/is_compatible(),
195  * re-evaluate the exception handling
196  * where they are used and update the docs for exception specifications.
197  * \todo hash_set needs more testing.
198  * \todo maybe we should rename is_container_element to is_regular_type.
199  * \todo the following items still remain to be finished up after the truncation rework:
200  * - re-evaluate the heuristic for choosing n_threads in fill_term_pointers, estimate_series_size, and the likes.
201  * Right now we are using the heuristic for series multiplication, but, at least in case of fill_term_pointers,
202  * it seems like we might be running in some overhead.
203  * - the fill_term_pointers parallelisation + deterministic ordering has not been done yet for rational coefficients.
204  * \todo in a bunch of generic constructors all over the place, we enable them only if the argument is not the same type
205  * as the calling class.
206  * This should probably be an is_base_of check, as done in forwarding.hpp, so that if one derives from the class then we
207  * are still not mixing
208  * up generic ctor and standard copy/move ones in the derived class.
209  * \todo we need to review the documentation/implementation of type traits were we strip away cv qualifications vs,
210  * e.g., implementing the test() method
211  * in terms of const references. I think in some cases it should be made more explicit and consistent across the type
212  * traits.
213  * \todo the multiplication of a series by single coefficient can probably be handled in the binary_mul_impl() method.
214  * \todo in mp_integer probably the ternary operations (and multadd etc.) should be modified so that the
215  * return value is demoted to
216  * static if the other operands are static as well. Right now, if one re-uses the same output object multiple times,
217  * once it is set to dynamic
218  * storage there's no going back. On the other hand, that is what one might want in some cases (e.g., a value that
219  * iteratively always increases).
220  * Not sure there's a general solution.
221  * \todo it seems like, at least in some cases, it is possible to avoid extra template arguments for enabling purposes
222  * if one uses static methods rather than instance methods (something related to the calling class not being a complete
223  * type). Keep this in mind in order to simplify signatures when dealing with compelx sfinae stuff.
224  * \todo need probably to provide an overload to math::evaluate() taking init list, for ease of use from C++.
225  * \todo is_unitary() should be implemented for real and series as well.
226  * \todo the evaluate requirements and type trait do not fail when the second type is a reference. this should be fixed
227  * in the type-traits rework.
228  * \todo in the pyranha doc improvements, we should probably handle better unspecified exceptions and document
229  * the return type as well for consistency (see lambdify docs) -> actually start using sphinx napoleon - UPDATE:
230  * note also that the settings' methods' docstrings need to be filled out properly with exception specs, return types,
231  * etc.
232  * \todo "quick install" should not be the title of the getting started section in sphinx
233  * \todo it seems like in C++17 we can finally have an automatically inited global class in which to tuck the init
234  * code (and probably the thread pool as well), via inline variables. Probably we will need to define it in a separate
235  * header and then make sure to include that header in every piranha public header.
236  * \todo the series multiplier estimation factor should probably be 1, but let's track performance before changing it.
237  * \todo guidelines for type traits modernization:
238  * - beautify enablers,
239  * - replace std::decay with uncvref_t,
240  * - check returnability,
241  * - key_* type traits should probably deal with cvref types (with respect, for instance, to the is_key check),
242  * in the same fashion as the s11n type traits.
243  * \todo instead of disabling debug checks at shutdown for series, maybe we should do like in Python and register an
244  * atexit() function to clean up custom derivatives before static destruction starts. We could register the atexit
245  * at the first invocation of register_custom_derivative() for each series type, set a flag and then query the flag each
246  * time. Or maybe when the static derivative registry is constructed the first time. Same goes for pow_caches.
247  * Probably the existing mutex can be resued as well. Probably it makes sense to keep both, as the existing method would
248  * work in a more generic fashion (or otherwise we need to make clear). More generally, we need to think if there's
249  * a robust way of sorting out the init/destruction sequence for the global state. Destruction is harder.
250  */
251 namespace piranha
252 {
253 
254 // Namespace for implementation details.
255 // Classes and functions defined in this namespace are non-documented implementation details.
256 // Users should never employ functionality implemented in this namespace.
257 namespace detail
258 {
259 }
260 
261 // Same as above, new version as inline namespace so we don't have to use detail:: everywhere.
262 inline namespace impl
263 {
264 }
265 
267 inline namespace literals
268 {
269 }
270 }
271 
272 #include <piranha/array_key.hpp>
273 #include <piranha/base_series_multiplier.hpp>
274 #include <piranha/binomial.hpp>
275 #include <piranha/cache_aligning_allocator.hpp>
276 #include <piranha/config.hpp>
277 #include <piranha/convert_to.hpp>
278 #include <piranha/debug_access.hpp>
279 #include <piranha/divisor.hpp>
280 #include <piranha/divisor_series.hpp>
281 #include <piranha/dynamic_aligning_allocator.hpp>
282 #include <piranha/exceptions.hpp>
283 #include <piranha/hash_set.hpp>
284 #include <piranha/init.hpp>
285 #include <piranha/invert.hpp>
286 #include <piranha/ipow_substitutable_series.hpp>
287 #include <piranha/is_cf.hpp>
288 #include <piranha/is_key.hpp>
289 #include <piranha/key_is_convertible.hpp>
290 #include <piranha/key_is_multipliable.hpp>
291 #include <piranha/kronecker_array.hpp>
292 #include <piranha/kronecker_monomial.hpp>
293 #include <piranha/lambdify.hpp>
294 #include <piranha/math.hpp>
295 #include <piranha/memory.hpp>
296 #include <piranha/monomial.hpp>
297 #include <piranha/mp_integer.hpp>
298 #include <piranha/mp_rational.hpp>
299 #include <piranha/poisson_series.hpp>
300 #include <piranha/polynomial.hpp>
301 #include <piranha/pow.hpp>
302 #include <piranha/power_series.hpp>
303 #include <piranha/print_coefficient.hpp>
304 #include <piranha/print_tex_coefficient.hpp>
305 #include <piranha/real.hpp>
306 #include <piranha/real_trigonometric_kronecker_monomial.hpp>
307 #include <piranha/runtime_info.hpp>
308 #include <piranha/s11n.hpp>
309 #include <piranha/safe_cast.hpp>
310 #include <piranha/series.hpp>
311 #include <piranha/series_multiplier.hpp>
312 #include <piranha/settings.hpp>
313 #include <piranha/small_vector.hpp>
314 #include <piranha/static_vector.hpp>
315 #include <piranha/substitutable_series.hpp>
316 #include <piranha/symbol_utils.hpp>
317 #include <piranha/t_substitutable_series.hpp>
318 #include <piranha/term.hpp>
319 #include <piranha/thread_barrier.hpp>
320 #include <piranha/thread_management.hpp>
321 #include <piranha/thread_pool.hpp>
322 #include <piranha/trigonometric_series.hpp>
323 #include <piranha/tuning.hpp>
324 #include <piranha/type_traits.hpp>
325 
326 #endif
Exceptions.
Root piranha namespace.
Definition: array_key.hpp:52
Type traits.
Low-level memory management functions.