Using boost multi precision operator instead of a const double one - c++

I have the following code for integration by boost library. Iam tried to change the double operator to cpp_dec_float_50 operator.
#include <iostream>
#include <boost/numeric/quadrature/adaptive.hpp>
#include <boost/numeric/quadrature/kronrodgauss.hpp>
#include <boost/numeric/quadrature/epsilon.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
namespace quadrature = boost::numeric::quadrature;
double polynomial(int k , int n);
struct f
{
vector<double> poly;
double polysum(double x) const {
double s = 0;
double p = 1;
for (int i = 1; i < poly.size(); i++) {
p = p * x;
s += p * poly[i];
}
return s;
}
double operator()(double x)const {
return polysum(x) * log(x) / (1 + x);
}
};
int main()
{
int n = 2;
f fun;
double p = 0;
for (int i = 0; i <= n; i++)
{
p = polynomial(i, n);
fun.poly.push_back(p);
}
double answer, error_estimate;
quadrature::adaptive().relative_accuracy(1e-5).absolute_accuracy(1e-7)
(fun, 0., 1., answer, error_estimate);
cout << "ans" << answer << endl;
return 0;
}
double polynomial(int k , int n)
{
return k;
}
if it changed to :
cpp_dec_float_50 operator()(cpp_dec_float_50 x) const {
and change all the related thing to cpp_dec_float_50, then a list of errors appear see them here
can any one fix that ?
for users who does not have Boost Quadrature library, u can download it from here https://github.com/coolfluid/coolfluid3/tree/master/include/boost/numeric

Related

Trying to implement Willans' formula for the n-th prime, what's the problem with my code?

The formula is listed in the following article: https://en.wikipedia.org/wiki/Formula_for_primes. I am trying to implement it but to no success, for whatever reason the code is producing number which seem to be nth power of two + 1, which is obviously not what I want to achieve.
#include <iostream>
#include <cmath>
using namespace std;
int nth_prime(int n) {
double s = 1;
for (int i = 1; i <= pow(2, n); i++) {
double c = 0;
for (int j = 1; j <= i; j++) {
double f = (tgamma(j)+1)/j;
c+=floor(pow(cos(M_PI*f), 2));
}
s+=floor(pow(n/c, 1/n));
}
return s;
}
int main() {
int n;
while (cin >> n) {
cout << nth_prime(n) << endl;
}
return 0;
}

error: 'int' is not a class, struct, or union type typedef typename _Iterator::iterator_category iterator_category;

I am trying this code about Kohonen Network:
// Fausett.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
double euclidean(double *vec1,double *vec2,int n)
{
double dist = 0.0;
for(int i=0;i<n;i++) dist += (vec1[i]-vec2[i])*(vec1[i]-vec2[i]);
return dist;
}
double distance(int i,int jstar)
{
return double(i!=jstar);
// returns 1.0 if i!=jstar, returns 0.0 if i==jstar
}
double h(double d) { return 1.0-d; }
void train(double **W,int n,int cols,double *vec,double rate)
{
int i,j;
int win = 0;
double windist = euclidean(W[0],vec,n),edist;
for(i=0;i<cols;i++){
if((edist=euclidean(W[i],vec,n)) < windist)
{ win = i; windist = edist;}
for(i=0;i<cols;i++)
for(j=0;j<n;j++)
W[i][j] += (rate*h(distance(i,win)))*(vec[j]-W[i][j]);
}
int main(void)
{
int i, j;
int T = 10000; // number of iterations
double eta = 0.6; // learning rate
const int m = 4;
int cols;
// training vectors
double x0[m] = { 1.0,1.0,0.0,0.0 };
double x1[m] = { 0.0,0.0,0.0,1.0 };
double x2[m] = { 1.0,0.0,0.0,0.0 };
double x3[m] = { 0.0,0.0,1.0,1.0 };
cout << "Enter number of columns for weight matrix: ";
cin >> cols;
double** W = NULL; W = new double*[cols];
for(i=0;i<cols;i++) W[i] = new double[m];
srand(time(NULL));
for(i=0;i<cols;i++)
for(j=0;j<m;j++) W[i][j] = rand()/double(RAND_MAX);
for(i=0;i<T;i++)
{
train(W,m,cols,x0,eta); train(W,m,cols,x1,eta);
train(W,m,cols,x2,eta); train(W,m,cols,x3,eta);
eta /= 1.05; // learning rate decreased
}
for(i=0;i<cols;i++)
{
cout << "W[" << i << "]= [";
for(j=0;j<m;j++) cout << W[i][j] << " ";
cout << "]" << endl;
}
for(i=0;i<cols;i++) delete[] W[i];
delete[] W;
return 0;
}
its from book Willi - Hans Steeb, I copy paste that, but it gives me error when compiled. error: 'int' is not a class, struct, or union type typedef typename _Iterator::iterator_category iterator_category, this is one of the error messages and I have no idea at all why this happen. Can someone please explain it? I am a newbie in C++.

Avoid blas when involving temporary memory allocation?

I have a program that computes the matrix product x'Ay repeatedly. Is it better practice to compute this by making calls to MKL's blas, i.e. cblas_dgemv and cblas_ddot, which requires allocating memory to a temporary vector, or is better to simply take the sum of x_i * a_ij * y_j? In other words, does MKL's blas theoretically add any value?
I benchmarked this for my laptop. There was virtually no difference in each of the tests, other than g++_no_blas performed twice as poorly as the other tests (why?). There was also no difference between O2, O3 and Ofast.
g++_blas_static 57ms
g++_blas_dynamic 58ms
g++_no_blas 100ms
icpc_blas_static 57ms
icpc_blas_dynamic 58ms
icpc_no_blas 58ms
util.h
#ifndef UTIL_H
#define UTIL_H
#include <random>
#include <memory>
#include <iostream>
struct rng
{
rng() : unif(0.0, 1.0)
{
}
std::default_random_engine re;
std::uniform_real_distribution<double> unif;
double rand_double()
{
return unif(re);
}
std::unique_ptr<double[]> generate_square_matrix(const unsigned N)
{
std::unique_ptr<double[]> p (new double[N * N]);
for (unsigned i = 0; i < N; ++i)
{
for (unsigned j = 0; j < N; ++j)
{
p.get()[i*N + j] = rand_double();
}
}
return p;
}
std::unique_ptr<double[]> generate_vector(const unsigned N)
{
std::unique_ptr<double[]> p (new double[N]);
for (unsigned i = 0; i < N; ++i)
{
p.get()[i] = rand_double();
}
return p;
}
};
#endif // UTIL_H
main.cpp
#include <iostream>
#include <iomanip>
#include <memory>
#include <chrono>
#include "util.h"
#include "mkl.h"
double vtmv_blas(double* x, double* A, double* y, const unsigned n)
{
double temp[n];
cblas_dgemv(CblasRowMajor, CblasNoTrans, n, n, 1.0, A, n, y, 1, 0.0, temp, 1);
return cblas_ddot(n, temp, 1, x, 1);
}
double vtmv_non_blas(double* x, double* A, double* y, const unsigned n)
{
double r = 0;
for (unsigned i = 0; i < n; ++i)
{
for (unsigned j = 0; j < n; ++j)
{
r += x[i] * A[i*n + j] * y[j];
}
}
return r;
}
int main()
{
std::cout << std::fixed;
std::cout << std::setprecision(2);
constexpr unsigned N = 10000;
rng r;
std::unique_ptr<double[]> A = r.generate_square_matrix(N);
std::unique_ptr<double[]> x = r.generate_vector(N);
std::unique_ptr<double[]> y = r.generate_vector(N);
auto start = std::chrono::system_clock::now();
const double prod = vtmv_blas(x.get(), A.get(), y.get(), N);
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
end - start);
std::cout << "Result: " << prod << std::endl;
std::cout << "Time (ms): " << duration.count() << std::endl;
GCC no blas is poor because it does not use vectorized SMID instructions, while others all do. icpc will auto-vectorize you loop.
You don't show your matrix size, but generally gemv is memory bound. As the matrix is much larger than a temp vector, eliminating it may not be able to increase the performance a lot.

c++ - Multithreading (integral function)

I am making a program that solves integrals. So far I managed to make a simple function integral (a,b) f(x)dx.
Now I need to make a Multithreading program in parallel programming using MPI.
This is how i see it. Need to make an array of elements for a,b,n(how precise i want my function solved) and then taking each combination of function elements for one thread.
Question : Am I understanding this problem correctly?
This is my code for functions and my epic fail trying to change it to array. Please help!
#include "stdafx.h"
#include <iostream>
#include "conio.h"
#include <stdio.h>
using namespace std;
void WaitForEnter(void)
{
printf("Press Enter to continue: ");
fflush(stdout);
while ( _getch() != '\n' ) ;
}
double fun (double x){return x;}//changing f(x)dx
double sumIntegral(double lowBound, int n, double dx)
{
double rectangleArea;
double cumSum=0;
for (int i=0; i<n; i++)
{
double xi = lowBound+i*dx;//x1,x2...
double funValue = fun(xi);
double rectangleArea = dx*funValue;
cumSum += rectangleArea;
}
return cumSum;
}
int main()
{
double lowBound = 4;//a
double upBound = 7 ;//b
int n = 5;//how precise is solution
double dx;
dx = (upBound-lowBound)/n;
double result = sumIntegral(lowBound , n, dx);
cout<<"rez je = "<<result;
WaitForEnter();
return 0;
}
//epic fail
#include "stdafx.h"
#include <iostream>
#include "conio.h"
#include <stdio.h>
using namespace std;
void WaitForEnter(void)
{
printf("Press Enter to continue: ");
fflush(stdout);
while ( _getch() != '\n' ) ;
}
double fun (double x){return x;}//menja funkciju
double sumIntegral(double lowBound[], int n, double dx[],int numBound)
{
double rectangleArea;
double cumSum;
double sumIntegralAll[] = {NULL};
for(int j=0;j<numBound;j++)
{
cumSum=0;
for (int i=0; i<n; i++)
{
double xi = lowBound[j]+i*dx[j];//x1,x2...
double funValue = fun(xi);
rectangleArea = dx[j]*funValue;
cumSum+=rectangleArea;
cout<<cumSum;
}
//sumIntegralAll[j]=cumSum;
}
for(int i=0;i<numBound;i++){cout<<sumIntegralAll;}//pise
return cumSum;
}
int main()
{
int numBound = 2;//broj do
double lowBound[] = {4,4};//a
double upBound[] = {7,7} ;//b
int n = 5;//broj intervala, preciznost
double dx[]={NULL};
for(int i=0;i<=numBound;i++){
dx[i] = (upBound[i]-lowBound[i])/n;
}
double result = sumIntegral(lowBound , n, dx,numBound);
//cout<<"rez je = "<<result;
WaitForEnter();
return 0;
}

Getting error message "Not declared in scope" [duplicate]

This question already has answers here:
Why is my HelloWorld function not declared in this scope?
(11 answers)
Closed 8 years ago.
I am working on a C++ project and while compiling, I am receiving the error messages:
error: mean was not declared in this scope
error: standard_dev was not declared in this scope
My code is
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
int N(0);
char filename[100];
double m, stdev;
string temp;
double next;
int count = 0;
cout << "Enter name of file: ";
cin >> filename;
ifstream myfile;
myfile.open(filename);
while (myfile >> next)
{
count++;
}
N = count;
double* mydata;
mydata = new double[N];
for (int i = 0; i < N; i++)
{
myfile >> mydata[i];
}
m = mean(mydata, N);
stdev = standard_dev(mydata, m, N);
cout << "The standard deviation is:" << stdev << endl;
myfile.close();
delete[] mydata;
return 0;
}
double mean(double* mydata, double N)
{
double sum(0), m;
for (int i = 0; i < N; i++)
{
sum += mydata[i];
}
m = (sum / (double) N);
return (m);
}
double standard_dev(double* mydata, double m, int N)
{
double* mydata2 = new double[N];
for (int i = 0; i < N; i++)
{
mydata2[i] = pow((mydata[i] - m), 2);
}
double sum(0), S, X;
for (int i = 0; i < N; i++)
{
sum += mydata2[i];
}
X = sum / N;
S = sqrt(X);
return (S);
}
Those functions have not been seen yet when you try to use them; the compiler doesn't know what they are which leads to the error. Either move them before main() or prototype them, such as:
double mean(double * mydata, double N);
double standard_dev(double * mydata, double m, int N);
int main()
{
...
This will give the compiler its expectations for those symbols, so when it sees them in use it knows what to do with them.
Any name must be defined before its using (with rare exceptions relative to template). You use name mean in statement
m = mean(mydata, N);
but name mean is not yet defined.
Place function declarations before main
double mean(double *mydata, double N);
double standard_dev(double *mydata, double m, int N);
int main()
{
//...
Or before their usage.
int main()
{
double mean(double *mydata, double N);
double standard_dev(double *mydata, double m, int N);
//...
m = mean(mydata, N);
//...
You need to have prototypes for your functions mean() and std_dev() at the top of your file. Otherwise, they don't 'exist' in the main function. Either copy the entire functions to the space above your main function, or make prototypes for them. Good luck!