Double approximation using lexical_cast - boost

When I use following line of code
std::wcout << boost::lexical_cast<std::wstring>(5.453) << std::endl;
I obtain the following result on the console
5.4530000000000003
What's be best way to approximate the number in order to obtain the same number that I use for conversion?

Related

how does libtorch get tensor device type?

Is there any method for libtorch to get the tensor or model device type.
Just like xxx.device in pytorch?
import torch
tensor = torch.rand(3,4)
print(tensor.device)
libtorch was designed to provide almost exactly the same features in C++ as in python, so when in doubt you can try :
#include <torch/torch.h>
torch::Tensor tensor = torch::rand({3,4});
std::cout << tensor.device() << std::endl;
Plot twist : it works \o/

Cannot programmatically change boost multiprecision mpfr precision

Keep in mind that Precision is based on the total number of digits and not the decimal places, but I need a way to set the Decimal places and all I can find is Precision, so I am trying to work with it, so I account for the number of digits in the whole number, in order to get this to work, but that is not working.
I want to do some math and return with a set precision value, the function takes a string of a very large number with a very large decimal precision and returns it as a string set to the number of decimals passed in as precision:
#include <boost/multiprecision/mpfr.hpp>
QString multiply(const QString &mThis, const QString &mThat, const unsigned int &precison)
{
typedef boost::multiprecision::number<mpfr_float_backend<0> > my_mpfr_float;
my_mpfr_float aThis(mThis.toStdString());
my_mpfr_float aThat(mThat.toStdString());
my_mpfr_float::default_precision(precison);
my_mpfr_float ans = (aThis * aThat);
return QString::fromStdString(ans.str());
}
I have tried it without the typedef, same problem;
MathWizard::multiply("123456789.123456789", "123456789.123456789", 20);
18 digits of Precision, 9 + 9, I should ask for 30
will return 22 decimal places
15241578780673678.51562
instead of 20
15241578780673678.516
So why is it off by 2?
I would like to make the precision change after the math, but it seems you have to set it before, and not like the examples that boost shows in their example, but still does not return the correct value, doing it after does not change value.
Update: Compare what I did to what they say works in this Post:
how to change at runtime number precision with boost::multiprecision
typedef number<gmp_float<0> > mpf_float;
mpfr_float a = 2;
mpfr_float::default_precision(1000);
std::cout << mpfr_float::default_precision() << std::endl;
std::cout << sqrt(a) << std::endl; // print root-2
I have noticed differences between gmp_float, mpf_float (using boost/multiprecision/gmp.hpp) and mpfr_float, and mpfr_float will give me a closer precision, for example, if I take the number (1/137):
mpf_float
0.007299270072992700729927007299270072992700729927007299270073
only 1 Precision, 23 digits when set to 13
0.00729927007299270072993
mpfr_float
0.007299270072992700729929
only 1 Precision, 16 digits when set to 13
0.0072992700729928
With only 1 Precision I would expect my answer to be have one less decimal.
The other data types do similar, I did try them all, so this code will work the same for all the data types described here:
boost 1.69.0: multiprecision Chapter 1
I also must point out that I rely on Qt since this function is used in a QtQuick Qml Felgo App, and actually I could not figure out to convert this to string without converting it to an exponent, even though I used ans.str() for both, my guess is that fromStdString does something different then std::string(ans.str()).
I figure if I can not figure his out, I will just do String Rounding to get the correct precision.
std::stringstream ss;
ss.imbue(std::locale(""));
ss << std::fixed << std::setprecision(int(precison)) << ans.str();
qDebug() << "divide(" << mThis << "/" << mThat << " # " << precison << " =" << QString::fromStdString(ss.str()) << ")";
return QString::fromStdString(ss.str());
I still could not get away without using QString, but this did not work, it returns 16 digits instead of 13, I know that is a different question, as such I just post it to show my alternatives do not work any better at this point. Also note that the divide function works the same as the multiply, I used used that example to show the math has nothing to do with this, but all the samples they are showing me do not seem to work correctly, and I do not understand why, so just to make the steps clear:
Create back end: typedef boost::multiprecision::number > my_mpfr_float;
Set Precision: my_mpfr_float::default_precision(precision);
Set initial value of variable: my_mpfr_float aThis(mThis.toStdString());
Do some math if you want, return value with correct Precision.
I must be missing something.
I know I can just get the length of the string, and if longer than Precision, then check if Precision + 1 is greater than 5, if so add 1 to Precision and return a substring of 0, Precision and be done with all this Correct way of doing things, I could even do this in JavaScript after the return, and just forget about doing it the Correct way, but I still think I am just missing something, because I can not believe this is the way this is actually supposed to work.
Submitted Bug Report: https://github.com/boostorg/multiprecision/issues/127

What is the use of swap() function in priority_queue class in C++?

I was exploring priority_queue class in C++ and couldn't think about any practical use of swap().
Ref: http://www.cplusplus.com/reference/queue/priority_queue/swap/
Can someone list a practical example where it is beneficial to use this function. Essentially it feels like renaming the priority queue variable.
std::priority_queue<int> foo,bar;
foo.push (15); foo.push(30); foo.push(10);
bar.push (101); bar.push(202);
foo.swap(bar);
std::cout << "size of foo: " << foo.size() << '\n';
std::cout << "size of bar: " << bar.size() << '\n';
swap is a library-wide feature; many of the classes in the standard library support swap. It's also a customization point; you can specialize std::swap for your own classes.
As to what it's useful for - there's lots of algorithms that use it (all the sorting algorithms, for example) and some of the containers use it internally.
A swap that is noexcept is a great tool for writing exception-safe code.

Proper save/restore of RNG state in boost::random behaving unexpectedly

I have a small test program that attempts to save and restore the state of a random number generator using boost::random, but it is not behaving as the documentation indicates. From the boost docs:
Classes which model a pseudo-random number generator should also model the Streamable concept, i.e. implement operator<< and operator>>. If so, operator<< writes all current state of the pseudo-random number generator to the given ostream so that operator>> can restore the state at a later time. The state shall be written in a platform-independent manner, but it is assumed that the locales used for writing and reading be the same. The pseudo-random number generator with the restored state and the original at the just-written state shall be equivalent.
As I understand it, if a RNG state is saved and then a number is pulled from it, the state should change. If the state is later restored, this should allow the exact same number to be generated as the generator has been rolled back. I made a test program that examines this, but at first glance it seems like the state is not restored. Consider the code:
unsigned int s = static_cast<unsigned int>(std::time(0));
//typedef boost::minstd_rand base_generator_type;
typedef boost::mt19937 base_generator_type;
base_generator_type randgen(s);
boost::uniform_01<base_generator_type> getrand(randgen);
//boost::normal_distribution<float> noise(0,1);
//boost::variate_generator<base_generator_type,
//boost::normal_distribution<float> > getrand(randgen, noise);
double numsbefore[2], numsrightafter[2], numsnew[4];
//generate a short sequence, save it, and display
numsbefore[0] = getrand();
numsbefore[1] = getrand();
cout << "First Sequence, before save: "
<< numsbefore[0] << " "
<< numsbefore[1] << endl;
//save the current RNG state to a file using the stream interface
std::ofstream rngfileout("test_rngfile.txt");
rngfileout << randgen;
rngfileout.close();
//generate the next two numbers and display
numsrightafter[0] = getrand();
numsrightafter[1] = getrand();
cout << "Next, right after save: "
<< numsrightafter[0] << " "
<< numsrightafter[1] << endl;
//read in the RNG state that was saved, back into the RNG, restoring the state
//to be such as it was prior to the most recent two calls to randgen()
std::ifstream rngfilein("test_rngfile.txt", ifstream::in);
if(!rngfilein.good())
{
cout << "Couldn't read from file\n";
return 0;
}
rngfilein >> randgen;
rngfilein.close();
//declare and initialize a new variate generator to the newly-restored generator
boost::uniform_01<base_generator_type> getrand2(randgen);
// boost::variate_generator<base_generator_type,
// boost::normal_distribution<float> > getrand2(randgen, noise);
//copy the new variate function into the old one, to allow us to use
//the old one on the restored generator
getrand = getrand2;
//generate the next sequence
//The first two should be the same as the most recent two called
//The next two should be new random numbers
numsnew[0] = getrand();
numsnew[1] = getrand();
numsnew[2] = getrand();
numsnew[3] = getrand();
cout << "Restored, Next: "
<< numsnew[0] << " "
<< numsnew[1] << " "
<< numsnew[2] << " "
<< numsnew[3] << endl;
The output for a given time seed is:
First Sequence, before save: 0.970021 0.266862
Next, right after save: 0.110485 0.267466
Restored, Next: 0.970021 0.266862 0.110485 0.267466
The code's comments illustrate what I think should be happening. Also, some lines include commented code to do the same test with a different generator and different distribution. The same problem occurs for any of those: the next two values taken from the generator randgen after the state has been restored are not the same as the two that are generated immediately after the save, as they should be.
Upon closer inspection (debugging), it appears that calls to the variate generator getrand() do not change the state of the generator randgen at all no matter how many times I call getrand() on it, and so when I save it, it remains the same as if it were just created, and thus, when I pull from it again after restoration, it just starts from the beginning.
Shouldn't each call to the generator cause the state to advance? How am I even getting sequences that are not the same numbers if the RNG state never changes? Is the generator I'm viewing/saving not the "real" one, or something?
Also, the assignment operation of getrand = getrand2 might look sketchy but the = operator is defined for those,and replacing the last 4 calls with getrand2() doesn't make a difference.
Is the generator I'm viewing/saving not the "real" one, or something?
That is indeed the case. The uniform_01 constructor you're using actually makes a copy of the provided engine, rather than taking a reference.
If you're using Boost 1.39 or later, you can use it like this instead:
boost::uniform_01<> getrand;
getrand(randgen);
If you're stuck on an older Boost and you don't need getrand to be copyable, changing uniform_01's type parameter from base_generator_type to base_generator_type& should also work.

Boost: How to print/convert posix_time::ptime in milliseconds from Epoch?

I am having trouble converting posix_time::ptime to a timestamp represented by time_t or posix_time::milliseconds, or any other appropriate type which can be easily printed (from Epoch).
I actually need just to print the timestamp represented by the posix_time::ptime in milliseconds, so if there is an easy way to print in that format, I don't actually need the conversion.
This code will print the number of milliseconds since 1941-12-07T00:00:00. Obviously, you can choose whatever epoch suits your need.
void print_ptime_in_ms_from_epoch(const boost::posix_time::ptime& pt)
{
using boost::posix_time::ptime;
using namespace boost::gregorian;
std::cout << (pt-ptime(date(1941, Dec, 7))).total_milliseconds() << "\n";
}

Resources