std::function wont print out trapezoidal integral, lamda won't take function parameter.

I need help with implementing the trapezoidal method in std::function and using the lambda function.

Is there a solution or a help to it?

I don't want to use a raw function pointer.

This is my code: It won't work, not because of syntax error.
But the function integral won't take in function as a parameter.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
// We have the Given function:
auto Function = [&](Doub x) -> Doub{return cos((x * x))* exp(-(x * x * x));};
std::function<Doub(Doub)> fun = Function;
		
// We will use trapezoidal method to integrate our function:
auto Trapezoid_Integral = [&](std::function<Doub(Doub)>& fun, Doub& a, Doub& b, Int& N)
{
Doub sum = 0;
Doub h = (b - a) / N;
for (int i = 1; i < N; i++) {
sum += fun(a + i * h);
}
return h / 2.0 * (fun(a) + fun(b) + 2 * sum);
};
std::function<Doub(std::function<Doub(Doub)>& fun, Doub& a, Doub& b, Int& N)> integral = Trapezoid_Integral;

// We have the given parameters:
int N = 2, a = 1, b = 4;
Doub acc = 1E-5;
while (true)
{
cout << Trapezoid_Integral(fun, a, b, N);
}
}
}
Last edited on
Anyway this isn't the best way to do it.
I don't want to use a raw function pointer.


Why not?
This compiles and runs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <functional>
#include <iostream>

using Doub = double;
using Int = int;

int main()
{
	// We have the Given function:
	auto Function = [&](Doub x) -> Doub {return cos((x * x)) * exp(-(x * x * x)); };
	std::function<Doub(Doub)> fun = Function;

	// We will use trapezoidal method to integrate our function:
	auto Trapezoid_Integral = [&](std::function<Doub(Doub)>& fun, Doub& a, Doub& b, Int& N)
	{
		Doub sum = 0;
		Doub h = (b - a) / N;

		for (int i = 1; i < N; i++) {
			sum += fun(a + i * h);
		}

		return h / 2.0 * (fun(a) + fun(b) + 2 * sum);
	};

	std::function<Doub(std::function<Doub(Doub)>& fun, Doub& a, Doub& b, Int& N)> integral = Trapezoid_Integral;

	// We have the given parameters:
	int N = 2;
	Doub a = 1, b = 4;

	std::cout << Trapezoid_Integral(fun, a, b, N);
}


The output is:


0.149075


I don't know if that's correct or not?
As long as it compiles and run, i am happy
Actually, it is not working:

The

Doub and Int are defined in NR3.h, which is exclusive for numerical method students only.
EDIT: error corrected now (I hope!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <cmath>
#include <iostream>
using namespace std;

double integrand( double x ){ return cos( x * x ) * exp ( -x * x * x ); }

double Trapezoid_Integral( double f( double ), double a, double b, int N )
{
   double sum = 0;
   double dx = ( b - a ) / N;
// ERROR *** for ( int i = 1; i < N; i++ ) sum += f( a + ( i - 0.5 ) * dx ); *** ERROR
   for ( int i = 1; i < N; i++ ) sum += f( a + i * dx );
   return dx * ( sum + 0.5 * ( f( a ) + f( b ) ) );
}

int main()
{
   int N = 1000;
   double a = 1.0, b = 4.0;
   cout << "Integral is " << Trapezoid_Integral( integrand, a, b, N ) << '\n';
   cout << "Integral is " << Trapezoid_Integral( []( double x ){ return cos( x * x ) * exp ( -x * x * x ); }, a, b, N ) << '\n';
}


Integral is 0.0121455
Integral is 0.0121455
Last edited on
As long as it compiles and run, i am happy

Can you come be my boss?
@lastchance

Using your implementation of Trapezoid_Integral:
1
2
3
4
5
double y_equals_x(double x) { return x; }
int main() {
    cout << Trapezoid_Integral(y_equals_x, 0.0, 1.0, 2) << '\n';
    cout << Trapezoid_Integral(y_equals_x, 0.0, 1.0, 8) << '\n';
}
0.375
0.445312


-Albatross
It's a good thing that you are keeping an eye on my bad code, Albatross! My previous effort was an unholy mix of trapezium rule and mid-ordinate rule. I hope that this is better.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cmath>
#include <iostream>
using namespace std;

double integrand( double x ){ return cos( x * x ) * exp ( -x * x * x ); }

double Trapezoid_Integral( double f( double ), double a, double b, int N )
{
   double sum = 0;
   double dx = ( b - a ) / N;
   for ( int i = 1; i < N; i++ ) sum += f( a + i * dx );
   return dx * ( sum + 0.5 * ( f( a ) + f( b ) ) );
}

int main()
{
   int N = 1000;
   double a = 1.0, b = 4.0;
   cout << "Integral is " << Trapezoid_Integral( integrand, a, b, N ) << '\n';
   cout << "Integral is " << Trapezoid_Integral( []( double x ){ return cos( x * x ) * exp ( -x * x * x ); }, a, b, N ) << '\n';
}


Integral is 0.0121455
Integral is 0.0121455





For Albatross's linear (and hence, in this case, exact-solution-giving) example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <cmath>
#include <iostream>
using namespace std;

double Trapezoid_Integral( double f( double ), double a, double b, int N )
{
   double sum = 0;
   double dx = ( b - a ) / N;
   for ( int i = 1; i < N; i++ ) sum += f( a + i * dx );
   return dx * ( sum + 0.5 * ( f( a ) + f( b ) ) );
}

int main()
{
   double a = 0.0, b = 1.0;
   for ( int N = 2; N <= 8; N *= 2 )
   {
      cout << "N: " << N << "    Integral: " << Trapezoid_Integral( []( double x ){ return x; }, a, b, N ) << '\n';
   }
}


N: 2    Integral: 0.5
N: 4    Integral: 0.5
N: 8    Integral: 0.5
Last edited on
Topic archived. No new replies allowed.