-
Notifications
You must be signed in to change notification settings - Fork 226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extended Precision Constants #505
Conversation
This is cool. I never really thought of that expressional form. Nice! If I catch your intention, you are picking up a bit on the syntax of C++20's I actually like to use an older form of syntax for the character strings. You can decide on column widths of 1,000 decimal digits or 100 decimal digits. An example with column widths of 1,000 decimal digist would look something like this below. Typing is tedious for sure. But I like columns of 100 decimal digits because of the order it adds. We tend to think in groups of 10^n.
|
The syntax is very similar to |
Awesome! Or use
Thank you. |
Before I comment in detail.... how does this differ from boost::math::constants ? OK I realise the syntax can be cleaner now that we're not C++03, but you could equally have written
And yes, the constants:: versions are constexpr and arbitrary precision already ;) |
Syntax aside I think the only major difference is the level of precision afforded to constexpr, or without calculation. Correct me if I am wrong but |
So for a lot of calculations-pi is certainly one of them, e another, computing the number is actually faster than pulling it off disk. That's a danger with this sort of thing. In addition, the parse is gonna be expensive. I'm intrigued by this attack but it's unclear to me that it's an improvement. It reminds me of the compression competitions where they had to make a rule that the winner must minimize the size of the data + compressor. We need to think about ways this might be unexpectedly expensive. |
Good advice to ponder! Or maybe the big strings even bring in unexpected dangers to break existing code or compiler memory systems somewhere out there if we try to parse 20 constants having 10,000 digits each. When I did some early, early research on this issue, as a compromise, I limited the string-constructables to a handful of constants, 1,101 digits. Maybe the 10,000 is a bit to rowdy? Thoughts? |
At runtime @NAThompson's suspicions are correct:
My question than becomes is there a use case for having >117 of digits of precision at compile time? That would really be the differentiating factor. |
It has layers of precision:
I think it depends on the constant as well. We actually have a number of competing constraints here:
Having said all that, this might be the time to rethink the interface to the Math lib constants now that we're not constrained by C++03. Coming up with a good way to manage the transition would be the biggest challenge I suspect? |
@mborland : I believe that what @ckormanyos was talking about in the feature wishlist was to make sure that the algorithms used to compute the constants were state of the art, so that the complexity of recovering each bit was as low as possible. 10,000 digits is just a stretch goal for that enterprise. (Is that correct Chris?) |
In a word, yes. In #303, I wrote:
The context of that wishlist entry was expressing an intent to improve the performance/efficiency of our constants calculations, with particular focus on those calculated via AGM algorithms, such as pi-related, root-related and logarithm-related constants. At that time, we were putting the finishing touches on Karatsuba multiplication for Returning to the root-based and logarithm-based constants, I still need to incormporate some of the key elements of the work from GSoC 2020 to improve the efficiency of high-precision logarithm-based constants, above a few hundred decimal digits. In my opinion, these are definitely worth the expected few tens of lines needed for the performance kicks. Also root-based constants can be significantly improved with the same general scope of effort. Some constants such as Catalan's constant will always remain difficult to compute, even with accelrated series methods. Admitedly, however, we do not perceive a loud cry in our community for tens of thousands of digits of Catalan's constant or other really special ones. So having said all that, I am particularly motivated by the advices of Nick and John, emphasizing caution with regard to incorporation of very large string-based compilation units. We could re-asses the meaning of providing about 117 decimal digits in string form. Does that have a physical derivation from somewhere? Is it just a nice amount that fits rather well on a modern page of code text? Or would we like to extend to a different number (albeit maybe not so stellarly high as 10,000) such as 129 or 201? |
Current string form constants provide 200-decimal place precision, it's an arbitrary number! |
Do you have anything particular in mind, or is it more of refactoring to C++11? |
Yes I was thinking of We could as you say have a high precision interface with the large strings in place, I guess the question is how much it will be used? @ckormanyos what was your use case for very high digit counts? |
Not Chris but mine was for PSLQ. The syntax of the constants library was really no problem for me; it's more the algorithms to generate those high digit counts being slow-although admittedly I don't know that faster algorithms exist. |
The tried and true... because they're there... comes to mind. I hammer out a million or a billion digits of pi as a matter of principle to test new computer/compiler systems --- also emedded controllers, their compilers and memory systems, usually with the modest million digits. I know if the C++11 compiler, the containers, custom allocators, the processor's FPU, memory system, caching, etc. handle the million digits error free, then things are looking good for middle-of-the-road embedded work in modern C++ on the system. I'll go up to 1,000 decimal digits or slightly higher for fractal imaging, but personally don't go deeper diving than that. Over the years, I did also identify high-precision numerical calculations in template-based modern C++ to be a really deep stress test of a real-time embedded compiler's C++ abilities --- that was a tangential discovery that influences some of the research work I am doing to this very day. |
Allow me to expand on that. I am a huge fan of Boost.Math and Boost.Multiprecision because of the modern template scalable treatment of numbers, constants and the special functions of pure and applied mathematics (and a whole lot more). I still have certain goals. In the future, I would like to be able to pull a million digits of pi or ln_two off the header-only rack of Boost any time, anywhere, portable, with any new compiler and no external libs whatsoever. (This I do crave, and it comes in addition to the countless built-in functions and lower-precision functions in multiprecision/math.) We are not quite there yet, but really getting rather close. |
@jzmaddock 27fc8b6 offers an example of a variable template wrapper around the current constant implementations. It matches the syntax from C++20s |
Don’t forget that std::constants was approved for C++20 see cplusplus/papers#107 https://wiki.edg.com/pub/Wg21cologne2019/LibraryWorkingGroup/D0631R8.pdf (reminder template) This is pretty much the cmath list at 128-bit precision (35ish decimal digits - increased from 80-bit at my suggestion). And this will meet most peoples needs? But looks a bit different from Boost.Math constants (and is a much smaller subset of values). I would have thought that it was only worth making any big changes to Boost.Math (to provide many more values not in the std::constants proposal) if we can make it work with a similar syntax to std::constants (meaning c++>11 and probably 20?), and avoid a compiler-time penalty for getting simple double pi. John's cunning scheme achieves a balance of a small penalty for double yet still providing a lot more digits for the greedy who want more and more pi! |
@pabristow 27fc8b6 offers an example of a thin wrapper around the current implementation to give the same syntax as
This allows |
Yes - but premature until many compilers support c++20 and ? On MSVC 14.2 latest preview, exists, but is not usable by the MS VS compiler, only Clang, for example. |
T old_pi = boost::math::constants::pi<T>(); | ||
T new_pi = boost::math::numbers::pi_hp<T>(); | ||
|
||
BOOST_TEST(abs(old_pi-new_pi) < tol); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i do not think it's correct to compare float in this way
As requested by @ckormanyos in the feature wish list. Does this interface look like what you had envisioned? Currently has a trivial (long double) version of pi and then the first 10'000 digits for non-trivial types.