calculating numerical integral in c++ [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to write a function that can calculate me inetegral e^(cos x) on range (a,b)
double integral(double(*f)(double x), double a, double b, int n) {
double step = (b - a) / n; // width of each small rectangle
double area = 0.0; // signed area
for (int i = 0; i < n; i ++) {
area += f(a + (i + 0.5) * step) * step; // sum up each small rectangle
}
return area;
}
This is what I have found but I`m new in c++ and I can't work with pointers
if there is another way please help me.

That function you found allows you to integrate any function you want, and that funcion is the first parameter of the integral method. You can just remove the first argument ('double(*f)(double x)' ), that is because the function you want to integrate is known ( e^cos(x)), so you don't need to give it as an argument. Then, in the for loop, you just replace de f function for e^cos(x). The method will look like this:
double integral(double a, double b, int n){
double step = (b - a) / n; // width of each small rectangle
double area = 0.0; // signed area
for (int i = 0; i < n; i ++) {
area += exp(cos(a + (i + 0.5) * step)) * step; // sum up each small rectangle
}
return area;
}

#include <functional>
template<typename T>
T integral(const std::function<T(T)>& f, T a, T b, int n) {
auto step = (b - a) / n; // width of each small rectangle
auto area = static_cast<T>(0); // signed area
for (auto i = 0; i < n; i++)
{
// sum up each small rectangle
area += f(a + (i + static_cast<T>( 0.5)) * step) * step;
}
return area;
}
int main()
{
std::function<float(float)> f_sine = [](float in) { return sin(in); };
auto two = integral(f_sine, 0.0f, 3.14f, 20);
return 0;
}
That will be $3.50

Related

Generating random points are so close together [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 29 days ago.
The community is reviewing whether to reopen this question as of 29 days ago.
Improve this question
I'm trying to generate a uniform gird, then selecting random points out of it. The problem is the points that are chosen are very close to each other. Here is my trial
Minmumal example : https://ideone.com/80jFm2
int random(int min, int max) //range : [min, max]
{
static bool first = true;
if (first)
{
srand(time(NULL)); //seeding for the first time only!
first = false;
}
return min + rand() % ((max + 1) - min);
}
jcv_point p1, p2, p3;
p1.x = 325;
p1.y = 239;
p2.x = 431;
p2.y = 448;
p3.x = 640;
p3.y = 685;
float radius = 100;
std::vector<jcv_point> grid;
std::vector<int> rand_nums;
for (int i = 20; i < 1000; i++)
{
for (int j = 20; j < 1000; j++)
{
float x = (float)i;
float y = (float)j;
float distance1 = sqrt(pow(p1.x - x, 2) + pow(p1.y - y, 2));
float distance2 = sqrt(pow(p2.x - x, 2) + pow(p2.y - y, 2));
float distance3 = sqrt(pow(p3.x - x, 2) + pow(p3.y - y, 2));
if (distance1 > radius && distance2 > radius && distance3 > radius)
{
jcv_point p;
p.x = x;
p.y = y;
grid.push_back(p);
int idx = random(0, grid.size());
rand_nums.push_back(idx%width);
}
}
}
points = (jcv_point*)malloc(sizeof(jcv_point) * (size_t)count);
for (int i = 0; i < count; ++i)
{
int idx = random(0, grid.size());
points[i] = grid[rand_nums[idx]];
}
In the first part of your code you have, basically:
// create new grid
for (x = ...)
for (y = ...)
// add a point to the grid
// generate a random number between 0 and grid.size
So your random numbers at first will be clustered at the low end. That is, first time you generate a random number between 0 and 1. Then between 0 and 2, etc., etc. As your grid size increases, the range of the random numbers grows, but overall your distribution will be skewed towards the low end.
Not sure what the point is of generating your random numbers and storing them when you build the grid. I also don't see the point of dividing the generated random number by the width. Seems like you could get the desired effect by generating random points after the entire grid is built.
Build the grid, then generate random numbers between 0 and grid.size.

Composite Simpson's Rule in C++

I've been trying to write a function to approximate an the value of an integral using the Composite Simpson's Rule.
template <typename func_type>
double simp_rule(double a, double b, int n, func_type f){
int i = 1; double area = 0;
double n2 = n;
double h = (b-a)/(n2-1), x=a;
while(i <= n){
area = area + f(x)*pow(2,i%2 + 1)*h/3;
x+=h;
i++;
}
area -= (f(a) * h/3);
area -= (f(b) * h/3);
return area;
}
What I do is multiply each value of the function by either 2 or 4 (and h/3) with pow(2,i%2 + 1) and subtract off the edges as these should only have a weight of 1.
At first, I thought it worked just fine, however, when I compared it to my Trapezoidal Method function it was way more inaccurate which shouldn't be the case.
This is a simpler version of a code I previously wrote which had the same problem, I thought that if I cleaned it up a little the problem would go away, but alas. From another post, I get the idea that there's something going on with the types and the operations I'm doing on them which results in loss of precision, but I just don't see it.
Edit:
For completeness, I was running it for e^x from 1 to zero
\\function to be approximated
double f(double x){ double a = exp(x); return a; }
int main() {
int n = 11; //this method works best for odd values of n
double e = exp(1);
double exact = e-1; //value of integral of e^x from 0 to 1
cout << simp_rule(0,1,n,f) - exact;
The Simpson's Rule uses this approximation to estimate a definite integral:
Where
and
So that there are n + 1 equally spaced sample points xi.
In the posted code, the parameter n passed to the function appears to be the number of points where the function is sampled (while in the previous formula n is the number of intervals, that's not a problem).
The (constant) distance between the points is calculated correctly
double h = (b - a) / (n - 1);
The while loop used to sum the weighted contributes of all the points iterates from x = a up to a point with an ascissa close to b, but probably not exactly b, due to rounding errors. This implies that the last calculated value of f, f(x_n), may be slightly different from the expected f(b).
This is nothing, though, compared to the error caused by the fact that those end points are summed inside the loop with the starting weight of 4 and then subtracted after the loop with weight 1, while all the inner points have their weight switched. As a matter of fact, this is what the code calculates:
Also, using
pow(2, i%2 + 1)
To generate the sequence 4, 2, 4, 2, ..., 4 is a waste, in terms of efficency, and may add (depending on the implementation) other unnecessary rounding errors.
The following algorithm shows how to obtain the same (fixed) result, without a call to that library function.
template <typename func_type>
double simpson_rule(double a, double b,
int n, // Number of intervals
func_type f)
{
double h = (b - a) / n;
// Internal sample points, there should be n - 1 of them
double sum_odds = 0.0;
for (int i = 1; i < n; i += 2)
{
sum_odds += f(a + i * h);
}
double sum_evens = 0.0;
for (int i = 2; i < n; i += 2)
{
sum_evens += f(a + i * h);
}
return (f(a) + f(b) + 2 * sum_evens + 4 * sum_odds) * h / 3;
}
Note that this function requires the number of intervals (e.g. use 10 instead of 11 to obtain the same results of OP's function) to be passed, not the number of points.
Testable here.
The above excellent and accepted solution could benefit from liberal use of std::fma() and templatize on the floating point type.
https://en.cppreference.com/w/cpp/numeric/math/fma
#include <cmath>
template <typename fptype, typename func_type>
double simpson_rule(fptype a, fptype b,
int n, // Number of intervals
func_type f)
{
fptype h = (b - a) / n;
// Internal sample points, there should be n - 1 of them
fptype sum_odds = 0.0;
for (int i = 1; i < n; i += 2)
{
sum_odds += f(std::fma(i,h,a));
}
fptype sum_evens = 0.0;
for (int i = 2; i < n; i += 2)
{
sum_evens += f(std::fma(i,h,a);
}
return (std::fma(2,sum_evens,f(a)) +
std::fma(4,sum_odds,f(b))) * h / 3;
}

Complex numbers arithmetic goes wrong [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Right now I am trying to implement the formula for the probabilities of a Poisson binomial distribution.
The formula is the last one in that section, with complex exponentials inside them:
I have a very simple code that should do it, but it is outputting wrong probabilities.
#include <iostream>
#include <complex>
#include <cmath>
using namespace std;
int main(int argc, char const *argv[]) {
int N=5; //number of coins
double probabilities[N]={0.1,0.1,0.1,0.1,0.1}; //probabilities of coin landing head
double distr[N+1];
for (int j=0; j<N+1;j++){
complex<double> temp1=0.0 + 0.0i;
for (int k=0; k<N+1;k++){
for(int l=0;l<N+1;l++){
complex<double> temp2=1.0 + 0.0i;
for (int m=0;m<N;m++){
temp2=temp2*(1.0+0.0i+(exp(l*2*M_PI*1.0i/(double(N)+1.0))-1.0+0.0i)*probabilities[m]);
}
temp2=temp2*exp(l*k*2*M_PI*1.0i/(double(N)+1.0));
temp1=temp1+temp2/(double(N)+1.0);
}
}
distr[j]=real(temp1);
}
for (int i=0;i<N+1;i++){
cout<< distr[i] << ' ';
}
The output of this code is [1,1,1,1,1,1], which is definitely not correct. I am thinking that maybe I have not been working correctly with complex numbers, but I do not see where I did something wrong. It is frustrating that such a simple program does not work :(.
From the code it is clear that temp1 does not depend on j, hence you get the same numbers, the sum over k. After you remove the outer loop over j and write distr[k] = real(temp1); and fix the sign in exp(l*k*...), you'll get the expected result:
0.59049 0.32805 0.0729 0.0081 0.00045 1e-05
Full code with some simplifications:
int main() {
using namespace std::literals::complex_literals;
constexpr int N = 5;
const double probabilities[N] = {.1, .1, .1, .1, .1};
const auto c = std::exp(2i * M_PI / (N + 1.));
double distr[N + 1];
for (int k = 0; k <= N; ++k) {
auto sum = std::complex<double>(0);
for(int l = 0; l <= N; ++l) {
auto prod = std::complex<double>(1);
for (int m = 0; m < N; ++m)
prod *= 1. + (std::pow(c, l) - 1.) * probabilities[m];
sum += prod * std::pow(c, -l * k) / (N + 1.);
}
distr[k] = std::real(sum);
}
for (auto d : distr)
std::cout << d << ' ';
}

Can I find quadratic function when Im being given x and y values? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I was doing an algorithm where Im given x and y solution, and I need to find if possible, quadratic formula for that solutions.
What I actually mean is:
If Im given output:
f(1) = 1
f(2) = 5
f(3) = 13
f(4) = 25
So, the function should return 1,5,13,25
Function that gives that output is: 2x^2-2x+1, but how do I get that?
If your y-values are precise, you can solve system of linear equations
a*x1^2 + b*x1 + c = y1
a*x2^2 + b*x2 + c = y2
a*x3^2 + b*x3 + c = y3
substitute known values for three points and find unknowns coefficients a,b,c
If values are approximate, use least squares method (more precise - polynomial least squares) with all points
This is piece of code for least sqaure analysis. It is written for newmat matrix library. Because i don't use it right now so i am too lazy to rewrite it into armadillo library i am currently using. Just to avoid mistakes newmat starts with vector/matrix indexes from 1 instead of 0.
void polynomial_approx( const vector<double>& x, const vector<double>& fx, vector<double>& coeff, int pd)
{
// x - input values of independent variable
// fx - input values of dependent variable
// coeff - output vector with polynomial coeffiecients
// pd - polynomial degree
if ( x.size() < pd ){
cerr << "Not enough data for such high polynomial degree." << endl;
};
coeff.clear();
Matrix A(x.size(), pd + 1);
Matrix D(pd+1,pd+1);
ColumnVector y(fx.size());
ColumnVector dx;
// converting vector from c++ type to newmat vector
for (unsigned int i = 0; i < fx.size(); i++)
y(i+1) = fx[i];
// creating the design matrix
for (unsigned int i = 1; i <= x.size();i++ ){
for (unsigned int j = 1; j<= pd+1;j++ ){
A(i,j) = pow(x[i],j-1);
}
}
// compute the unknown coefficients
dx = (A.t() * A ).i() * A.t() * y;
for (unsigned int i = 1; i<= dx.Ncols(); i++)
coeff.push_back( dx(i) );
/* reconstruction of polynomial */
vector<double> recon (x.size(), 0.0 );
for ( unsigned int i = 0; i < x.size() ; i++){
for ( unsigned int j = 0; j< coeff.size(); j++){
recon[i] += coeff[j]*pow( x[i], (double) j );
}
}
}

Monte Carlo Sims - Please check my algorithm

Basically, the problem simulates the following:
There is an urn with 50 green balls and 50 red balls.
I am allowed to pick balls from the urn, without replacement, with the following rules: For every red ball picked, I lose a dollar, for every green ball picked, I gain a dollar.
I can stop picking whenever I want. Worst case scenario is I pick all 100, and net 0.
The question is to come up with an optimal stopping strategy, and create a program to compute the expected value of the strategy.
My strategy is to continue picking balls, while the expected value of picking another ball is positive.
That is, the stopping rule is DYNAMIC.
In Latex, here's the recursive formula in an image:
http://i.stack.imgur.com/fnzYk.jpg
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double ExpectedValue(double, double);
double max(double, double);
main() {
double g = 50;
double r = 50;
double EV = ExpectedValue(g, r);
printf ("%f\n\n", EV);
system("PAUSE");
}
double ExpectedValue(double g, double r){
double p = (g / (g + r));
double q = 1 - p;
if (g == 0)
return r;
if (r == 0)
return 0;
double E_gr = max ((p * ExpectedValue (g - 1, r)) + (q * ExpectedValue (g, r - 1)), (r - g));
return E_gr;
}
double max(double a, double b){
if (a > b)
return a;
else return b;
}
I let it run for 30 minutes, and it was still working.
For small values of g and r, a solution is computed very quickly. What am I doing wrong?
Any help is much appreciated!
Your algorithm is fine, but you are wasting information. For a certain pair (g, r) you calculate it's ExpectedValue and then you throw that information away. Often with recursion algorithms remembering previously calculated values can speed it up a LOT.
The following code runs in the blink of an eye. For example for g = r = 5000 it calculates 36.900218 in 1 sec. It remembers previous calculations of ExpectedValue(g, r) to prevent unnecessary recursion and recalculation.
#include <stdio.h>
#include <stdlib.h>
double ExpectedValue(int g, int r, double ***expectedvalues);
inline double max(double, double);
int main(int argc, char *argv[]) {
int g = 50;
int r = 50;
int i, j;
double **expectedvalues = malloc(sizeof(double*) * (g+1));
// initialise
for (i = 0; i < (g+1); i++) {
expectedvalues[i] = malloc(sizeof(double) * (r+1));
for (j = 0; j < (r+1); j++) {
expectedvalues[i][j] = -1.0;
}
}
double EV = ExpectedValue(g, r, &expectedvalues);
printf("%f\n\n", EV);
// free memory
for (i = 0; i < (g+1); i++) free(expectedvalues[i]);
free(expectedvalues);
return 0;
}
double ExpectedValue(int g, int r, double ***expectedvalues) {
if (g == 0) return r;
if (r == 0) return 0;
// did we calculate this before? If yes, then return that value
if ((*expectedvalues)[g][r] != -1.0) return (*expectedvalues)[g][r];
double p = (double) g / (g + r);
double E_gr = max(p * ExpectedValue(g-1, r, expectedvalues) + (1.0-p) * ExpectedValue(g, r-1, expectedvalues), (double) (r-g));
// store value for later lookup
(*expectedvalues)[g][r] = E_gr;
return E_gr;
}
double max(double a, double b) {
if (a > b) return a;
else return b;
}
Roughly speaking, adding one ball to the urn doubles the number of calls you will have to make to ExpectedValue (let's not quibble about boundary conditions). This is called O(en), and it can bring the most powerful computer on Earth to its knees.
The problem is that you are calculating the same values over and over again. Keep a table of ExpectedValue(r,g) and fill it in as you go, so that you never have to calculate the same value more than once. Then you'll be working in O(n2), which is heck of a lot faster.
In my opinion, correct, but rather straightforward solution.
Here's what you can do:
Eliminate recursion!
Eliminate recalulations of ExpectedValue
Parallelize your code
Read this [lecture notes]. It definitely will be useful
I can provide some code samples, but it'd not be fair.