wrong result boost gmp float - boost

I need to compute 5^64 with boost multiprecision library which should yield 542101086242752217003726400434970855712890625 but boost::multiprecision::pow() takes mpfloat and gives 542101086242752217003726392492611895881105408.
However If I loop and repeatedly multiply using mpint I get correct result.
Is it a bug ? or I am using boost::multiprecision::pow() in a wrong way ? or I there is an alternative of using boost::multiprecision::pow() ?
#include <iostream>
#include <string>
#include <boost/multiprecision/gmp.hpp>
typedef boost::multiprecision::mpz_int mpint;
typedef boost::multiprecision::number<boost::multiprecision::gmp_float<4> > mpfloat;
int main(){
mpfloat p = boost::multiprecision::pow(mpfloat(5), mpfloat(64));
std::cout << p.template convert_to<mpint>() << std::endl;
mpint res(1);
for(int i = 0; i < 64; ++i){
res = res * 5;
}
std::cout << res << std::endl;
}

Related

How to access map in vector for building trie

#include <string>
#include <iostream>
#include <vector>
#include <map>
using std::map;
using std::vector;
using std::string;
typedef map<char, int> edges;
typedef vector<edges> trie;
trie build_trie(vector<string> & patterns) {
trie t;
// write your code here
for(int j=0;j<patterns.size();j++){
//current NOde = root;
int currNI=0;
for(int i=0;i<patterns[j].size();i++){
char currS = patterns[j][i];
auto it = t[currNI].begin();
//auto mit = it->edges.begin();
if(t[currNI].edges.find(currS)!=t[currNI].edges.end()){
currNI = t[currNI].edges.find(currS)->second;
}else{
t.push_back(edges.insert(currS,t.size()));
t[currNI].edges.insert(currS,t.size());
currNI = t.size();
}
}
}
return t;
}
int main() {
size_t n;
std::cin >> n;
vector<string> patterns;
for (size_t i = 0; i < n; i++) {
string s;
std::cin >> s;
patterns.push_back(s);
}
trie t = build_trie(patterns);
for (size_t i = 0; i < t.size(); ++i) {
for (const auto & j : t[i]) {
std::cout << i << "->" << j.second << ":" << j.first << "\n";
}
}
return 0;
}
Hi I was trying to build trie using vector and map but I am not able to access elements of map.
I have also added image of pseudo code for better clarity.
I have used iterators and many other tricks that are already present on stackoverflow and on other platform but somehow I am not able to access what I want.
Thank You
To answer your questions: in your code, edges is a type, not an object.
t[currNI] is of type edges, thus is a map<char, int>.
You should try t[currNI].find(currS) and t[currNI].end() directly.
NB: after you fix this, there are still other errors in your code.

OpenBlas parallelisation from OpenMP Thread

I tried to call an OpenBlas function from an OpenMP thread while the Blas parallelisation is set to a value unequal to one. I am using OpenBlas 0.3.9, after downloading the source I untared it and called
make USE_OPENMP=1
make PREFIX=/someFolder/ install
However I always get the following error message from my executeable
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
Does anyone know, why this is the case and how I can change it? Here is a minimal example of my code:
#include <complex>
#include <vector>
#include <random>
#include <iostream>
#include <algorithm>
#include <omp.h>
#include <cblas.h>
#include <lapacke.h>
int main(int, char**) {
int const blas_threads = 2,
omp_threads = 2,
matrix_size = 100;
openblas_set_num_threads(blas_threads);
omp_set_max_active_levels(2);
double alpha = 1.,
beta = 0.;
std::vector<std::vector<double>> as(omp_threads,
std::vector<double>(matrix_size*matrix_size));
std::vector<std::vector<double>> bs(omp_threads,
std::vector<double>(matrix_size*matrix_size));
std::vector<std::vector<double>> cs(omp_threads,
std::vector<double>(matrix_size*matrix_size));
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> dis;
for(int i = 0; i < omp_threads; ++i) {
std::generate(as[i].begin(),
as[i].end(),
[&dis,&gen]() { return dis(gen); });
std::generate(bs[i].begin(),
bs[i].end(),
[&dis,&gen]() { return dis(gen); });
}
// for(int i = 0; i < matrix_size*matrix_size; ++i) {
// std::cout << as[0][i] << " " << bs[0][i] << std::endl;
// }
#pragma omp parallel for num_threads(omp_threads), schedule(static, 1)
for(int i = 0; i < omp_threads; ++i) {
cblas_dgemm(CblasColMajor,
CblasNoTrans,
CblasNoTrans,
matrix_size,
matrix_size,
matrix_size,
alpha,
as[i].data(),
matrix_size,
bs[i].data(),
matrix_size,
beta,
cs[i].data(),
matrix_size);
}
// for(int i = 0; i < matrix_size*matrix_size; ++i) {
// std::cout << cs[0][i] << std::endl;
// }
return 0;
}

<random> generates same number in Windows, but not in Linux

I do not why, but in Windows (with MinGW) this code generates for 3/4 time the same pseudo-random number.
I think that is because I set badly the seed, but I can not correct it.
Thank you for your help.
Here there is the code:
#include <iostream>
#include <random>
#include <chrono>
int main()
{
double Nprove = 50.0;
double p = 0.2;
const int Ncampioni = 100; // number of samples
int cappa = 0;
double sample[Ncampioni];
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937 gen(seed);
std::binomial_distribution<> d(Nprove, 0.9);
for(cappa = 0; cappa < Ncampioni; cappa = cappa +1){
sample[cappa] = d(gen);
std::cout << cappa << "," << sample[cappa] << std::endl;
}
}

Giving up ownership of a memory without releasing it by shared_ptr

Is there a way I can make the shared pointer point to a different memory location without releasing the memory.pointed by it currently
Please consider the code:
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
int
main()
{
int *p = new int();
*p = 10;
int *q = new int();
*q = 20;
boost::shared_ptr<int> ps(p);
// This leads to a compiler error
ps = boost::make_shared<int>(q);
std::cout << *p << std::endl;
std::cout << *q << std::endl;
return 0;
}
You can't.
Of course you can release and reattach, while changing the deleter to a no-op
To be honest, it looks like you'd just want
ps = boost::make_shared<int>(*q);
Prints (live on Coliru):
0
20

Interleave random numbers

I would like to interleave a random number with some alphanumeric characters, for example: HELLO mixed with the random number 25635 → H2E5L6L3O5. I know %1d controls the spacing, although I'm not sure how to interleave text between the random numbers or how accomplish this.
Code:
int main(void) {
int i;
srand(time(NULL));
for (i = 1; i <= 10; i++) {
printf("%1d", 0 + (rand() % 10));
if (i % 5 == 0) {
printf("\n");
}
}
return 0;
}
btw - if my random number generator isn't very good i'm open to suggestions - thanks
If you're okay with using C++11, you could use something like this:
#include <iostream>
#include <random>
#include <string>
int main() {
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> uniform_dist(0, 9);
std::string word = "HELLO";
for (auto ch : word) {
std::cout << ch << uniform_dist(e1);
}
std::cout << '\n';
}
...which produces e.g.:
H3E6L6L1O5
If you're stuck with an older compiler, you could use rand and srand from the standard C library for your random numbers:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
int main() {
std::srand(std::time(NULL));
std::string word = "HELLO";
for (int i = 0; i < word.size(); ++i) {
std::cout << word[i] << (rand() % 10);
}
std::cout << '\n';
}

Resources