boost:multiprecision - c++

I have just started using boost::multiprecision trying to speed up some calculations previously done in Matlab. I found quite an unexpected problem, though. My calculations involve complex numbers, so I am using cpp_complex_50 type (e.g. cpp_complex_50 A, B;)
At some point I need to use boost::math::tools::bracket_and_solve_root() function, which requires that the function it works on returns real values. Here comes my problem... I cannot convert my complex multiprecision variable A.real() to any type that is real, eg. to cpp_dec_float_50 type or even double. The task should be streightforward, but I am virtually drowned in error complaints from my compiler (MSVC2015), and cannot solve it. Any hints at how to convert the data are more than welcome.
A somewhat connected question is the problem of initialization of cpp_complex_50 type variables with real values. At the moment I can only use data of type double at initialization, which means I am loosing some accuracy at the initialization stage already, e.g.:
cpp_complex_50 A = 4.0 * boost::math::constants::pi<double>(); // it works
but
cpp_complex_50 A = 4.0 * boost::math::constants::pi<cpp_dec_float_50>(); // It does NOT work
Any hints are needed. I am stuck at this, despite nice initial results.
Regards
Pawel

cpp_complex uses cpp_bin_float.
Live On Compiler Explorer
#include <boost/multiprecision/cpp_complex.hpp>
#include <iostream>
namespace bmp = boost::multiprecision;
int main() {
using Complex = bmp::cpp_complex_100;
using Real = Complex::value_type;
Real r = 4.0 * boost::math::constants::pi<Real>();
Complex b(r, {});
// or
b = r.convert_to<Complex>();
std::cout << b.str(100) << std::endl;
}
Prints
12.56637061435917295385057353311801153678867759750042328389977836923126562514483599451213930136846827

Following valuable comment from sehe... the code
cpp_complex_50 A = 4.0 * boost::math::constants::pi<cpp_bin_float_50>();
cout << A << endl;
works, producing:
12.5663706143591729538505735331180115367886775975
Similarely,
cpp_bin_float_50 B = A.real();
cout << B << endl;
works as well, printing the same.

Related

Namespaced Functions interfering with print

I'm new to the site and browsed several similar sounding questions but haven't found my exact problem. I suspect I'm making elementary mistakes. A link to an answer would be appreciated, or an explanation, and again I'm sorry if my question doesn't even match the title of the post.
For c++ on the Cxxdroid app for android and in Visual Studio C++:
I'm trying to experiment with classes and namespaces to provide flexible utility to the class. I want to use different implementations of the same function for personal analysis of certain algorithms on data structures; namely arrays vs lists/trees and also between recursive and iterative implementations of standard procedures. I know how to do asymptotic analysis but my stubborn mind wants real numbers.
Unfortunately, however, I can't even seem to get namespace functions to work without blowing up normal functionality. Please note, I haven't learned c++ formally yet because I'm exploring ahead of my introductory c/c++ course.
For example:
#include <iostream>
namespace iterative{
int power(int base,int expo){...}
}
namespace recursive{
int power(int base,int expo){...}
}
int main(int argc,char* argv[]){
int result = 0;
int num = 3;
int exp = 2;
//Expecting 9 in result
std::cout << "This prints fine" << std::endl;
result = iterative::power(num,exp);
std::cout << result;
std::cout << " This number and text doesn't print" << std::endl;
return 1;
}
I had a much more complex function with classes above the namespaced functions (search function for node classes inside a list/tree class) but it never worked. Then I just threw together the above snippet and tried to print result but the std::cout never fired after my function call.
Can anyone offer insight into what I'm doing wrong here? The first cout prints and the second wont. Further, execution hangs during the function call; the solution keeps running until I force it to stop.
I've tried to comment out one of the namespaces while using the other.
I've tried the using keyword with the namespace_name.
I've tried passing integers without variable usage: result = power(3,2);
I've tried printing the function result directly: std::cout << power(3,2) << std::endl;
I can't seem to get it to work on either application. I know this seems like a silly and simple question but after about a week of browsing the internet I'm inundated with very vague answers to questions regarding syntax. Perhaps I'm just not connecting the dots to my own problem...
Is my syntax in definition wrong?
Is my syntax in calling the function wrong?
Is my syntax in variable assignment wrong?
I'm at my wits' end.
Edit:
Now I feel really stupid.
You were correct. I didn't increment my variable in the iterative implementation, which meant it hung up on an infinite loop. I had to print the loop to see the numbers spitting out like I'm Neo in The Matrix. Unfortunately, I didn't test the recursive function because it felt dangerous to do so if I couldn't even get the iterative function to call first...
I was so focused on using namespaces for the first time that I never looked at the loop properly.
Thank you, and sorry for the bother. I'm going to try to extend this experiment to namespace-defining class member functions now.
Edit2: Feel free to delete this...unless it's felt that my stupidity can help others.
Silly mistake was made:
...
int power(int base,int expo){
int i = 0;
int retval = 1;
while( i < expo ){
retval *= base;
//Never did i++; or i = i + 1;
//Had to std::cout << retval; in loop to catch it
}
return retval;
}
...

Declaring constants or using numbers inside the code

So, i have this C++ test and the teacher is really hard on declaring constants instead of using numbers directly in the code. In the example below i have even declared ZERO as a constant.
Is this unnecessary or is this a good thing to do? Does this way take up more memory or make the code "slower"?
int main() {
int kmStart, kmEnd;
const int ZERO = 0;
cout << "Starting Kms? ";
cin >> kmStart;
cout << "Ending Kms? ";
cin >> kmEnd;
while (kmStart < ZERO || kmStart > kmEnd) {
cout << "Invalid Input!" << endl << endl;
cout << "Starting Kms? ";
cin >> kmStart;
cout << "Ending Kms? ";
cin >> kmEnd;
}
}
constexpr int ZERO = 0; would almost certainly be completely compiled out.
Note the new keyword constexpr, from C++11 onwards.
For you current code, ZERO may well be compiled out, but even if it isn't any degradation in performance will be negligible cf. the input / output functions.
I wonder why your teacher regards ZERO to be clearer than 0. Everyone knows what they are dealing with when they see a 0. For example, ZERO could feasibly mean '0', or even "0" which are entirely different beasts: you'd always have be checking back through the code when debugging this.
Use of properly named constants is mandatory for a development of long-living applications. Managing plain numeric literals quickly goes off hands. Consider the following example:
foo(42);
bar(42);
It has several problems:
it is not possible to guess where 42 value came from
it is not possible to guess whether 42 in both function calls is just a coincidence or we are intentionally passing the same value
as a consequence of the previous point changing program behavior may be challenging because we need to manually identify all the places where particular value that we want to adjust is utilized
If your application consists of hundreds of files it will be a literal nightmare.
So if constants are used instead the example code piece may become
constexpr int const fast_foobing_rate{42};
constexpr int const slow_barring_coeff{42};
foo(fast_foobing_rate);
bar(slow_barring_coeff);
or
constexpr int const days_in_week_count{7};
constexpr int const frobbing_weeks_count{6};
inline constexpr int get_frob_repetitions_count(void) noexcept
{
return(days_in_week_count * frobbing_weeks_count);
}
foo(get_frob_repetitions_count());
bar(get_frob_repetitions_count());
So now:
we are able to track origins of values
we can locate places where these persistent values are used
we can easily adjust these persistent values by modifying their definitions and our changes will be automatically applied across the entire codebase
And with all these benefits we won't suffer from performance penalties. Depending on constant type there could even be some benefits for performance as well.
In general, using constants instead of numbers in the code directly can make your code more readable and easier to maintain.
Consider the following example:
For example you have some kind of simulation with a timestep of 0.1 seconds and you need this timestep value in different locations of your source code, then it would be easier to use a
const double timesstep = 0.1
instead of writing 0.1 every where.
Advantage is:
only one line must be changed if you want to change the value of
timestep
the code becomes more readable, if you know the constants meaning
But in your case, I think its more readable to use 0 instead of zero, or you rename it to something more expressive as "minimum_start" or something like that...
Personnaly, for integer constant I am using enumerations (source == Scott Meyer, Effective C++) :
int main (int argc, char* argv []) {
enum Constant {
NTRY = 32,
NEQ = 8,
SMAX = 200000000,
ALERT = 65536
};
size_t ntry (Constant::NTRY);
std::cout << "ntry == " << ntry << std::endl;
return 0;
}

Error in using max function with Armadillo sparse matrices

Here is the code that I am getting error(type mismatch) on line no. with max:
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include<armadillo>
using namespace std;
using namespace arma;
int main(int argc, char** argv) {
umat loc;
loc<<0<<0<<3<<endr
<<2<<4<<4<<endr;
vec val={1,2,3};
sp_mat m(loc,val);
double t=arma::max(sum(square(m),1)) + 1.0;
cout<<t<<endl;
return 0;
}
Can somebody tell me why is that error happening and how to get around this.
Note: cout<<max(sum(square(m),1)) prints the result to console but adding any number to the output flags error.
If you want to convert a 1x1 matrix into a pure scalar (like double), use the as_scalar() function. Same goes for any Armadillo expression that results in a 1x1 matrix.
It's a good idea to read the Armadillo documentation thoroughly before posting questions on Stackoverflow.
Modifying your example:
umat loc = { { 0, 0, 3 },
{ 2, 4, 4 } };
vec val = {1, 2, 3};
sp_mat m(loc,val);
m.print("m:");
max(sum(square(m),1)).print("expression:");
double t = as_scalar( max(sum(square(m),1)) );
cout << t << endl;
You haven't told us (and I can't find in the documentation) exactly what data type is returned by arma::max(sum(square(m),1))
You have tested that whatever it is does not implicitly convert to double and whatever it is can be sent to a stream and when that is done it looks like a double.
My guess is it is something that can be explicitly converted to double so try:
(double)arma::max(sum(square(m),1)) + 1.0
The documentation shows the returned value for a dense matrix being used to initialize a double so that is obviously a type than can be explicitly converted to double. I had initially missed the thing you linked for me effectively saying sum does something on sparse matrix compatible with what it does on dense. So you can almost conclude (rather than just guess) that max(sum(m)) should be the same type (explicitly convertible to double).
If that doesn't work, we will really need a full quote of the error message, not just a summary of what it seems to mean.
Now that we have an error message, we can see this is a flaw in Armadillo's template metaprogramming:
Operations are stacked in template meta programming in order to avoid creating excess temporary objects. Then the meta programming must resolve the whole mess when the result is used.
If this is a minor flaw in the meta programming, you could add just one trivial temporary to fix it:
double t = arma::max(sum(square(m),1));
cout << t+1.0 endl;
But you probably already tried that. So you may need more temporaries and you probably need to give them exact correct types (rather than use auto). My first guess would be:
colvec v = sum(square(m),1);
Then see what works with arma::max(v)
(Earlier I made a negative comment on an answer that suggested starting with auto temporaries for each step. That answer was deleted. It wasn't far wrong. But I'd still say it was wrong to start there without seeing the template meta-programming failures and likely, though I'm not sure, wrong to use auto to try to bypass a meta-programming failure.)

Can std::vector<std::complex<boost:multiprecision::float128>>(N).data() safely be reinterpret_casted to fftwq_complex*?

I did not really expect the following example to work, but indeed it does (g++ 4.6.4, with --std=c++0x):
#include <boost/multiprecision/float128.hpp>
#include <blitz/array.h>
#include <fftw3.h>
int main(int /*argc*/, char** /*argv*/)
{
//these are the same
std::cout << sizeof(std::complex<boost::multiprecision::float128>) << " " << sizeof(fftwq_complex) << std::endl;
typedef std::vector< std::complex<boost::multiprecision::float128> > boost128cvec;
//typedef std::vector<std::complex<boost::multiprecision::float128> , fftw::allocator< std::complex<boost::multiprecision::float128> > > boost128cvec;
//declare a std::vector consisting of std::complex<boost::multiprecision::float128>
boost128cvec test_vector3(12);
//casting its data storatge to fftwq_complex*
fftwq_complex* test_ptr3 = reinterpret_cast<fftwq_complex*>(test_vector3.data());
//also create a view to the same data as a blitz::Array
blitz::Array<std::complex<boost::multiprecision::float128>, 1> test_array3(test_vector3.data(), blitz::TinyVector<int, 1>(12), blitz::neverDeleteData);
test_vector3[3] = std::complex<boost::multiprecision::float128>(1.23,4.56);
//this line would not work with std::vector
test_array3 = sin(test_array3);
//this line would not work with the built-in type __float128
test_vector3[4] = sin(test_vector3[3]);
//all of those print the same numbers
std::cout << "fftw::vector: " << test_vector3[3].real() << " + i " << test_vector3[3].imag() << std::endl;
std::cout << "fftw_complex: " << (long double)test_ptr3[3][0] << " + i " << (long double)test_ptr3[3][1] << std::endl;
std::cout << "blitz: " << test_array3(3).real() << " + i " << test_array3(3).imag() << std::endl << std::endl;
}
Two remarks:
The goal is to be able to use both fftw and blitz::Array operations on the same data without the need to copy them around while at the same time being able to use generic funcionst like sin() also for complex variables with quad precision
The blitz-part works fine, which is expected. But the surprise (to me) was, that the fftwq_complex* part also works fine.
The fftw::allocator is a simple replacement to std::allocator which will use fftwq_malloc to assure correct simd alignment, but that is not important for this question, so I left it out (at least I think that this is not important for this question)
My Question is: How thin is the ice I'm stepping on?
You're pretty much save:
std::vector is compatible with a C array (you can access a pointer to the first element via vector.data(), as answered in this question
std::complex<T> is designed to be compatible with a Array of form T[2], which is compatible with FFTW. This is described in the FFTW documentation
C++ has its own complex template class, defined in the standard header file. Reportedly, the C++ standards committee has recently agreed to mandate that the storage format used for this type be binary-compatible with the C99 type, i.e. an array T[2] with consecutive real [0] and imaginary [1] parts. (See report http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2002/n1388.pdf WG21/N1388.) Although not part of the official standard as of this writing, the proposal stated that: “This solution has been tested with all current major implementations of the standard library and shown to be working.” To the extent that this is true, if you have a variable complex *x, you can pass it directly to FFTW via reinterpret_cast(x).
The only thing to keep in mind is that the data() gets invalidated if you add values to your vector.
For the last part there is the compatiblity between boost::multiprecision::float128 and __float128. The boost documentation gives no guarantee about this.
What can be done however, is to add some static asserts in your code, which fails if the conversion is not possible. This could look like this:
static_assert(std::is_standard_layout<float128>::value,"no standard type");
static_assert(sizeof(float128) == sizeof(__float128),"size mismatch");
Where sizeof guarantees the same size of the boost type and __float128, and is_standard_layout checks that:
A pointer to a standard-layout class may be converted (with reinterpret_cast) to a pointer to its first non-static data member and vice versa.
Of course, this only gives hints if it works in the end, as you cannot say if the type is really a __float128, but ab boost states their type is a thin wrapper around it, it should be fine. If their are changes in design or structure of float128, the static assertions should fail.

std::chrono & Boost.Units

I'm working on a software design in which I'd like to leverage Boost.Units. Some of the units I'd like to use represent time, however, I'm inclined to use the C++11 std::chrono units for those since they're standard.
I'm wondering if there's any clean integration between Boost.Units and chrono or whether I have to resort to writing my own converters and lose type safety by just copying scalar values between the types.
Are there any best practices for this issue?
If you just want to convert a std::chrono duration to a boost time quantity you can use the following template function:
using time_quantity = boost::units::quantity<si::time, double>;
template<class _Period1, class _Type>
time_quantity toBoostTime( chrono::duration<_Type, _Period1> in)
{
return time_quantity::from_value(double(in.count()) * double(_Period1::num) / double(_Period1::den) );
}
One thing to note is that the returned time_quantity will always be in seconds and the storage type will be of type double. If any of those two are a problem, the template can be adapted.
Example:
namespace bu = boost::units;
namespace sc = std::chrono;
using time_quantity_ms = bu::quantity<decltype(bu::si::milli * bu::si::second), int32_t>;
std::cout << "Test 1: " << toBoostTime(sc::seconds(10)) << std::endl;
std::cout << "Test 2: " << toBoostTime(sc::milliseconds(10)) << std::endl;
std::cout << "Test 3: " << static_cast<time_quantity_ms>(toBoostTime(sc::milliseconds(10))) << std::endl;
/* OUTPUT */
Test 1: 10 s
Test 2: 0.01 s
Test 3: 10 ms
This may not be a perfect answer, but boost::chrono provides an example of how to integrate it with a units system they define in the example itself (devel) (version at time of writing).
Essentially, based on the boost.units examples for quaternion and complex numbers it should be possible to define the same functions for the std::chrono units, though it may require additional code for new user-defined units.
There is also a similar, though slightly different question regarding boost::date_time which may also have useful information.
Sorry this isn't a full answer, but perhaps it will be a start someone else can complete!