Spliting multiple variable C++ functions for quadrature integration - c++

I want to numerically integrate with boost::math::quadrature::trapezoidal(g, a, b, 1e-6); Here I'm integrating the function g(x). The problem is that I have to perform a double integral. Furthermore, I have 4 variables in the function I want to integrate. 2 of them I pass while integrating (m,n) and the other 2 are the integration variables (r,z). This is the integral I want to compute:
$$
\int_0^b\int_0^af(r,z)\sin{(\frac{n\pi}{a}z)}J_0(\frac{\alpha_{0,m}}{b}r)dzdr
$$
I saw this example Performing 2d numerical integration with Boost Cpp and notices that he uses lambda functions to split the main integrand in 2. so far I have managed this
double integrate(int m, int n)
{
auto f1 = [](double r, double z, int m, int n) { return integrand(r,z,m,n); };
auto f = [&](double r, m) {
auto g = [&](double z, n) {
return f1(r, z);
};
//return gauss_kronrod<double, 61>::integrate(g, 0, a, 5);
return boost::math::quadrature::trapezoidal(g, 0, a, 1e-6);
};
double error;
//double Q = gauss_kronrod<double, 15>::integrate(f, 0, b, 5, 1e-9, &error);
double Q = boost::math::quadrature::trapezoidal(f, 0, b, 1e-6);
//std::cout << Q << ", error estimated at " << error <<std::endl;
return Q;
}
The implementation of the function $f(r,z)$ and the rest of the integral is the following
double initial(double r, double z, int m, int n)
{
return std::sin(M_PI*n*z/a)*std::cyl_bessel_j(0, boost::math::cyl_bessel_j_zero(0,m)*r/b);
}
double integrand(double r,double z,int n,int m)
{
return initial(r,z,m,n)*std::sin(M_PI*n*z/a)*std::cyl_bessel_j(0, boost::math::cyl_bessel_j_zero(0,m)*r/b);
}
Normally the Initial won't need them and n variables but in this case, I need to make some tests.
The problem is that I really don't understand how to split my function like in the example for my problem and perform the integration because boost only accepts 1 variable functions.
Please help

The basic idea is, as usual, to integrate in two steps. For this you first solve the inner integral and make another one-dimensional function out of it, which you then pass again to the integrator.
The lambda is used whenever you want to cut down a multi-parameter function to a single-parameter function. In this case, you put all that is not the integrated variable in the lambda capture.
Here is the pseudo-code:
double integrand(double r,double z, int m,int n, double a, double b)
{
//this is the function you want to integrate
}
double integrate(int m, int n)
{
double a=1.0;
double b=1.0;
auto inner_integral = [m,n,a,b](double z)
{
auto f = [z,m,n,a,b](double r) { return integrand(r,z,m,n,a,b);}
return trapezoidal(f,0,a);
}
return trapezoidal(inner_integral,0,b);
};
You probably don't need to write out the lambda capture, i.e. a reference capture with & will likely work as well (auto inner_integral = [&](double z){...}).

Related

Pass a function as argument, without knowlegde of number of arguments of this function [duplicate]

long time browser, first time asker here. I've written a number of scripts for doing various 1D numerical integration methods and compiled them into a library. I would like that library to be as flexible as possible regarding what it is capable of integrating.
Here I include an example: a very simple trapezoidal rule example where I pass a pointer to the function to be integrated.
// Numerically integrate (*f) from a to b
// using the trapezoidal rule.
double trap(double (*f)(double), double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += (*f)(xi); }
else { s += 2*(*f)(xi); }
}
s *= (b-a)/(2*N);
return s;
}
This works great for simple functions that only take one argument. Example:
double a = trap(sin,0,1);
However, sometimes I may want to integrate something that has more parameters, like a quadratic polynomial. In this example, the coefficients would be defined by the user before the integration. Example code:
// arbitrary quadratic polynomial
double quad(double A, double B, double C, double x) {
return (A*pow(x,2) + B*x + C);
}
Ideally, I would be able to do something like this to integrate it:
double b = trap(quad(1,2,3),0,1);
But clearly that doesn't work. I have gotten around this problem by defining a class that has the coefficients as members and the function of interest as a member function:
class Model {
double A,B,C;
public:
Model() { A = 0; B = 0; C = 0; }
Model(double x, double y, double z) { A = x; B = y; C = z; }
double func(double x) { return (A*pow(x,2)+B*x+C); }
};
However, then my integration function needs to change to take an object as input instead of a function pointer:
// Numerically integrate model.func from a to b
// using the trapezoidal rule.
double trap(Model poly, double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += poly.func(xi); }
else { s += 2*poly.func(xi); }
}
s *= (b-a)/(2*N);
return s;
}
This works fine, but the resulting library is not very independent, since it needs the class Model to be defined somewhere. Also, ideally the Model should be able to change from user-to-user so I wouldn't want to fix it in a header file. I have tried to use function templates and functors to get this to work but it is not very independent since again, the template should be defined in a header file (unless you want to explicitly instantiate, which I don't).
So, to sum up: is there any way I can get my integration functions to accept arbitrary 1D functions with a variable number of input parameters while still remaining independent enough that they can be compiled into a stand-alone library? Thanks in advance for the suggestions.
What you need is templates and std::bind() (or its boost::bind() counterpart if you can't afford C++11). For instance, this is what your trap() function would become:
template<typename F>
double trap(F&& f, double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += f(xi); }
// ^
else { s += 2* f(xi); }
// ^
}
s *= (b-a)/(2*N);
return s;
}
Notice, that we are generalizing from function pointers and allow any type of callable objects (including a C++11 lambda, for instance) to be passed in. Therefore, the syntax for invoking the user-provided function is not *f(param) (which only works for function pointers), but just f(param).
Concerning the flexibility, let's consider two hardcoded functions (and pretend them to be meaningful):
double foo(double x)
{
return x * 2;
}
double bar(double x, double y, double z, double t)
{
return x + y * (z - t);
}
You can now provide both the first function directly in input to trap(), or the result of binding the last three arguments of the second function to some particular value (you have free choice on which arguments to bind):
#include <functional>
int main()
{
trap(foo, 0, 42);
trap(std::bind(bar, std::placeholders::_1, 42, 1729, 0), 0, 42);
}
Of course, you can get even more flexibility with lambdas:
#include <functional>
#include <iostream>
int main()
{
trap(foo, 0, 42);
trap(std::bind(bar, std::placeholders::_1, 42, 1729, 0), 0, 42);
int x = 1729; // Or the result of some computation...
int y = 42; // Or some particular state information...
trap([&] (double d) -> double
{
x += 42 * d; // Or some meaningful computation...
y = 1; // Or some meaningful operation...
return x;
}, 0, 42);
std::cout << y; // Prints 1
}
And you can also pass your own stateful functors tp trap(), or some callable objects wrapped in an std::function object (or boost::function if you can't afford C++11). The choice is pretty wide.
Here is a live example.
What you trying to do is to make this possible
trap( quad, 1, 2, 3, 0, 1 );
With C++11 we have alias template and variadic template
template< typename... Ts >
using custom_function_t = double (*f) ( double, Ts... );
above define a custom_function_t that take a double and variable numbers of arguments.
so your trap function becomes
template< typename... Ts >
double trap( custom_function_t<Ts...> f, Ts... args, double a, double b ) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += f(xi, args...); }
else { s += 2*f(xi, args...); }
}
s *= (b-a)/(2*N);
return s;
}
Usage:
double foo ( double X ) {
return X;
}
double quad( double X, double A, double B, double C ) {
return(A*pow(x,2) + B*x + C);
}
int main() {
double result_foo = trap( foo, 0, 1 );
double result_quad = trap( quad, 1, 2, 3, 0, 1 ); // 1, 2, 3 == A, B, C respectively
}
Tested on Apple LLVM 4.2 compiler.

Integrate a function of three variables C++

I spent quiet some time looking on the internet to find a solution to this, maybe it's out there but nothing of what I saw helped me.
I have a function !
double integrand(double r, double phi, double theta)
That I want to integrate with some given definite bounds over the three dimensions. I found multiple lines of code on the internet that implement single variable definite integrals numerical schemes. I was thinking to myself "well, I'll just integrate along one dimension after the other".
Algorithmically speaking what I wanted to do was :
double firstIntegral(double r, double phi) {
double result = integrationFunction(integrand,lower_bound,upper_bound);
return result;
}
And simply do it again two more times. This works easily in languages like Matlab where I can create functions handler anywhere but I don't know how to do it in C++. I would have to first define a function that some r and phi will calculate integrand(r, phi, theta) for any theta and make it in C++ a function of one variable only but I don't know how to do that.
How can I compute the triple integral of my three-variables function in C++ using a one -dimensional integration routine (or anything else really...) ?
This is a very slow and inexact version for integrals over cartesian coordinates, which should work with C++11.
It is using std::function and lambdas to implement the numerical integration. No steps have been taken to optimize this.
A template based solution could be much faster (by several orders of magnitude) than this, because it may allow the compiler to inline and simplify some of the code.
#include<functional>
#include<iostream>
static double integrand(double /*x*/, double y, double /*z*/)
{
return y;
}
double integrate_1d(std::function<double(double)> const &func, double lower, double upper)
{
static const double increment = 0.001;
double integral = 0.0;
for(double x = lower; x < upper; x+=increment) {
integral += func(x) * increment;
}
return integral;
}
double integrate_2d(std::function<double(double, double)> const &func, double lower1, double upper1, double lower2, double upper2)
{
static const double increment = 0.001;
double integral = 0.0;
for(double x = lower2; x < upper2; x+=increment) {
auto func_x = [=](double y){ return func(x, y);};
integral += integrate_1d(func_x, lower1, upper1) * increment;
}
return integral;
}
double integrate_3d(std::function<double(double, double, double)> const &func,
double lower1, double upper1,
double lower2, double upper2,
double lower3, double upper3)
{
static const double increment = 0.001;
double integral = 0.0;
for(double x = lower3; x < upper3; x+=increment) {
auto func_x = [=](double y, double z){ return func(x, y, z);};
integral += integrate_2d(func_x, lower1, upper1, lower2, upper2) * increment;
}
return integral;
}
int main()
{
double integral = integrate_3d(integrand, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
std::cout << "Triple integral: " << integral << std::endl;
return 0;
}
You can use functors
#include <iostream>
struct MyFunctorMultiply
{
double m_coeff;
MyFunctorMultiply(double coeff)
{
m_coeff = coeff;
}
double operator()(double value)
{
return m_coeff * value;
}
};
struct MyFunctorAdd
{
double m_a;
MyFunctorAdd(double a)
{
m_a = a;
}
double operator()(double value)
{
return m_a + value;
}
};
template<class t_functor>
double calculate(t_functor functor, double value, double other_param)
{
return functor(value) - other_param;
}
int main()
{
MyFunctorMultiply multiply2(2.);
MyFunctorAdd add3(3.);
double result_a = calculate(multiply2, 4, 1); // should obtain 4 * 2 - 1 = 7
double result_b = calculate(add3, 5, 6); // should obtain 5 + 3 - 6 = 2
std::cout << result_a << std::endl;
std::cout << result_b << std::endl;
}
If your concern is just about getting the right prototype to pass to the integration function, you can very well use alternative data passing mechanisms, the simpler of which is using global variables.
Assuming that the order of integration is on theta, then phi, then r, write three functions of a single argument:
It(theta) computes the integrand from the argument theta passed explicitly and the global phi and r.
Ip(phi) computes the bounds on theta from the argument phi passed explicitly and the global r; it also copies the phi argument to the global variable and invokes integrationFunction(It, lower_t, upper_t).
Ir(r) computes the bounds on phi from the argument r passed explicitly; it also copies the r argument to the global variable and invokes integrationFunction(Ip, lower_p, upper_p).
Now you are ready to call integrationFunction(Ir, lower_r, upper_r).
It may also be that integrationFunction supports a "context" argument where you can store what you want.

Fluctuating values in Newton Raphson

I'm trying to find N root using Newton Raphson method. Here is my implementation for the same...
double derive(int guess, int m, int n) {
return guess - (pow(guess, n)-m)/(n*pow(guess, n-1));
}
double getNRoot(int m, int n) {
double guess = 1;
double nextGuess = derive(guess, m, n);
while (fabs(guess-nextGuess) >= 0.0001) {
guess = nextGuess;
nextGuess = derive(guess, m, n);
printf ("%f %f\n", guess, nextGuess);
}
return nextGuess;
}
It works for many values, but for m=8 and n=4. The guess and nextGuess fluctuates between two values when m=8 and n=4.
2.750000 1.750000
1.750000 2.750000
2.750000 1.750000
...
So what is wrong here?
The derive function returns a double but manipulate int variables. Even if on function call you supply int, you can put doubles in the function prototype to have the proper precision:
double derive(double guess, double m, double n) {
return guess - (pow(guess, n)-m)/(n*pow(guess, n-1));
}
Or at least declare local double variables for the non-pow uses:
double derive(int guess, int m, int n) {
double d_guess = guess;
double d_n = n;
double d_m = m
return d_guess - (pow(d_guess, n)-d_m)/(d_n*pow(d_guess, n-1));
}
You should probably review you whole implementation considering that. That is, use doubles when "real" numbers are needed and "int" where "integer" numbers are used.

C++: pass function with arbitrary number of parameters as a parameter

long time browser, first time asker here. I've written a number of scripts for doing various 1D numerical integration methods and compiled them into a library. I would like that library to be as flexible as possible regarding what it is capable of integrating.
Here I include an example: a very simple trapezoidal rule example where I pass a pointer to the function to be integrated.
// Numerically integrate (*f) from a to b
// using the trapezoidal rule.
double trap(double (*f)(double), double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += (*f)(xi); }
else { s += 2*(*f)(xi); }
}
s *= (b-a)/(2*N);
return s;
}
This works great for simple functions that only take one argument. Example:
double a = trap(sin,0,1);
However, sometimes I may want to integrate something that has more parameters, like a quadratic polynomial. In this example, the coefficients would be defined by the user before the integration. Example code:
// arbitrary quadratic polynomial
double quad(double A, double B, double C, double x) {
return (A*pow(x,2) + B*x + C);
}
Ideally, I would be able to do something like this to integrate it:
double b = trap(quad(1,2,3),0,1);
But clearly that doesn't work. I have gotten around this problem by defining a class that has the coefficients as members and the function of interest as a member function:
class Model {
double A,B,C;
public:
Model() { A = 0; B = 0; C = 0; }
Model(double x, double y, double z) { A = x; B = y; C = z; }
double func(double x) { return (A*pow(x,2)+B*x+C); }
};
However, then my integration function needs to change to take an object as input instead of a function pointer:
// Numerically integrate model.func from a to b
// using the trapezoidal rule.
double trap(Model poly, double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += poly.func(xi); }
else { s += 2*poly.func(xi); }
}
s *= (b-a)/(2*N);
return s;
}
This works fine, but the resulting library is not very independent, since it needs the class Model to be defined somewhere. Also, ideally the Model should be able to change from user-to-user so I wouldn't want to fix it in a header file. I have tried to use function templates and functors to get this to work but it is not very independent since again, the template should be defined in a header file (unless you want to explicitly instantiate, which I don't).
So, to sum up: is there any way I can get my integration functions to accept arbitrary 1D functions with a variable number of input parameters while still remaining independent enough that they can be compiled into a stand-alone library? Thanks in advance for the suggestions.
What you need is templates and std::bind() (or its boost::bind() counterpart if you can't afford C++11). For instance, this is what your trap() function would become:
template<typename F>
double trap(F&& f, double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += f(xi); }
// ^
else { s += 2* f(xi); }
// ^
}
s *= (b-a)/(2*N);
return s;
}
Notice, that we are generalizing from function pointers and allow any type of callable objects (including a C++11 lambda, for instance) to be passed in. Therefore, the syntax for invoking the user-provided function is not *f(param) (which only works for function pointers), but just f(param).
Concerning the flexibility, let's consider two hardcoded functions (and pretend them to be meaningful):
double foo(double x)
{
return x * 2;
}
double bar(double x, double y, double z, double t)
{
return x + y * (z - t);
}
You can now provide both the first function directly in input to trap(), or the result of binding the last three arguments of the second function to some particular value (you have free choice on which arguments to bind):
#include <functional>
int main()
{
trap(foo, 0, 42);
trap(std::bind(bar, std::placeholders::_1, 42, 1729, 0), 0, 42);
}
Of course, you can get even more flexibility with lambdas:
#include <functional>
#include <iostream>
int main()
{
trap(foo, 0, 42);
trap(std::bind(bar, std::placeholders::_1, 42, 1729, 0), 0, 42);
int x = 1729; // Or the result of some computation...
int y = 42; // Or some particular state information...
trap([&] (double d) -> double
{
x += 42 * d; // Or some meaningful computation...
y = 1; // Or some meaningful operation...
return x;
}, 0, 42);
std::cout << y; // Prints 1
}
And you can also pass your own stateful functors tp trap(), or some callable objects wrapped in an std::function object (or boost::function if you can't afford C++11). The choice is pretty wide.
Here is a live example.
What you trying to do is to make this possible
trap( quad, 1, 2, 3, 0, 1 );
With C++11 we have alias template and variadic template
template< typename... Ts >
using custom_function_t = double (*f) ( double, Ts... );
above define a custom_function_t that take a double and variable numbers of arguments.
so your trap function becomes
template< typename... Ts >
double trap( custom_function_t<Ts...> f, Ts... args, double a, double b ) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += f(xi, args...); }
else { s += 2*f(xi, args...); }
}
s *= (b-a)/(2*N);
return s;
}
Usage:
double foo ( double X ) {
return X;
}
double quad( double X, double A, double B, double C ) {
return(A*pow(x,2) + B*x + C);
}
int main() {
double result_foo = trap( foo, 0, 1 );
double result_quad = trap( quad, 1, 2, 3, 0, 1 ); // 1, 2, 3 == A, B, C respectively
}
Tested on Apple LLVM 4.2 compiler.

recursion issue (2d quadrature)

So I have a program that implements an adaptive 2D trapezoidal rule on the function x^2 + y^2 < 1, but it seems that the recursion isn't working -- the program here is a modified form of a (working) 1D trapezoidal method so I'm not sure where the code breaks down, it should return PI:
double trapezoidal(d_fp_d f,
double a, double b,
double c, double d) { //helper function
return 0.25*(b-a)*(d-c)*
(f(a, c)+f(a, d) +
f(b, c)+f(b, d));
}
double atrap( double a, double b, double c, double d, d_fp_d f, double tol )
{// helper function
return atrap1(a, b, c, d, f, tol );
}
double atrap1( double a, double b, double c, double d, d_fp_d f, double tol)
{
//implements 2D trap rule
static int level = 0;
const static int minLevel = 4;
const static int maxLevel = 30;
++level;
double m1 = (a + b)/2.0;
double m2 = (c + d)/2.0;
double coarse = trapezoidal(f,a,b,c,d);
double fine =
trapezoidal(f, a, m1, c, m2)
+ trapezoidal(f, a, m1, m2, d)
+ trapezoidal(f, m1, b, c, m2)
+ trapezoidal(f, m1, b, m2, d);
++fnEvals;
if( level< minLevel
|| ( abs( fine - coarse ) > 3.0*tol && level < maxLevel ) ){
fine = atrap1( a, m1, c, m2, f,tol/4.0)
+ atrap1( a, m1, m2, d, f, tol/4.0)
+ atrap1(m1, b, c, m2, f, tol/4.0)
+ atrap1(m1, b, m2, d, f,tol/4.0);
}
--level;
return fine;
}
where the function is given by
double ucircle( double x, double y)
{
return x*x + y*y < 1 ? 1.0 : 0.0;
}
and my main function is
int main()
{
double a, b, c, d;
cout << "Enter a: " <<endl;
cin >> a;
cout << "Enter b: " <<endl;
cin >> b;
cout << "Enter c: " <<endl;
cin >> c;
cout << "Enter d: " <<endl;
cin >> d;
cout << "The approximate integral is: " << atrap( a, b, c, d, ucircle, 1.0e-5) << endl;
return 0;
}
It will not actually run forever, but it actually run for a very long time that you think it is running for ever and that is the reason: in first run level is one and function enter your if and it call itself 4 times, now consider first time: it is also enter the if and call itself 4 more times and it continue ... for correctly chosen input like one specified by you, condition abs(fine - coarse) is always true so only thing that can stop the flow from entering the if is level that will be increased and then decreased so your function will be called almost 4^30 and that's really a big number that you can't see its end in an hour or 2!
Like BigBoss already wrote, your program should finish, it would just take a long time since 30 recursions mean 4^30 function calls for atrap1, which is 1152921504606846976. Just let that number sink in.
Here are some more things to consider:
You probably wanted to use fabs instead of abs in the "break condition". (I think you should get a warning for integer conversion - or something similar - for this) abs may return unpredictable values for float or double parameters. Very high values.
tol seems to be a variable that represents a target precision value. However, with each recursion you further increase this target precision. At the 10th recursion it's already about 1E-11. Not sure this is intended. Whatever tol means.
You probably don't want the /4.0 (the .0 is redundant by the way) in your recursive calls.
You do compile this with optimization, right?
trapezoidal, minLevel, maxLevel could be macros.
Your function does not like threaded execution due to level being static. You should make it a parameter for atrap1.