In you lambda expression, you have to capture B_local :

    auto f = [&](Real x) { return std::bind(f0, _1, B_local)(x); };

The [&] tells the compiler to capture variables by reference automatically.

On Mon, Aug 17, 2020 at 2:26 AM Anirban Pal via Boost-users <boost-users@lists.boost.org> wrote:

Thank you John and Paul for your responses. Allow me to be more clear.

I’m considering something like the following function f0, which depends on x and some additional arguments given by the vector A. The vector A is unknown at compile time and computed during execution. The function f0 is to be integrated at a constant value for A (computed at runtime) with a range for x. The range is also computed at runtime, but it can be explicitly passed to the integrator.integrate call.

Lambda expressions seem to be the way to go. However, lambda expressions do not seem to easily capture local variables. In the following code, I've managed to get a lambda expression for the function f(x) = f0(x,A) and I can integrate that. However, I can only use the global variable B_global instead of B_local.

#include <iostream>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/quadrature/tanh_sinh.hpp>
#include <boost/bind/bind.hpp>
#include <functional>

typedef boost::multiprecision::cpp_bin_float_100 Real;

Real B_global[] = {0.0, 0.5, 1.0};

Real f0 (Real x, Real *A)
{
    return x*( A[0]*A[0] + A[1]*A[1] + A[2]*A[2] );
}

int main(int argc, char **argv)
{
    using namespace boost::math::quadrature;
    using namespace std::placeholders;
    tanh_sinh<Real> integrator;

    Real *B_local; B_local = (Real *)malloc(3*sizeof(Real));
    B_local[0] = 0.0; B_local[1] = 0.5, B_local[2] = 1.0;

    auto f = [](Real x) { return std::bind(f0, _1, B_global)(x); }; //If I use B_local, I get the error: ‘B_local’ is not captured
    Real Q = integrator.integrate(f, 0.0, 1.0);

    std::cout << std::setprecision(std::numeric_limits<Real>::max_digits10)
     << "Comp.: " << Q << std::endl;

    return 0;
}



I figured I need to use boost::bind.
Also, I wanted to use boost:bind but I was unsuccessful. So I retreated to std::bind for now.

Thank you.


On Sun, 16 Aug 2020 at 06:51, John Maddock via Boost-users <boost-users@lists.boost.org> wrote:

On 14/08/2020 22:56, Anirban Pal via Boost-users wrote:
> Hello,
>
> I'm trying to integrate functions with BOOST quadrature routines. So
> far they have been extremely impressive accuracy-wise, particularly
> with multiprecision features.
>
> I wish to integrate a function and pass some arguments to it. These
> arguments can be scalars, matrices, structs or objects. I was
> wondering if there is an example that explores this. Would I need to
> use a boost.function? Or would a function pointer work?

To create a reusable single-valued functor that integrates from [a, x]
for fixed a, then I think some nested lambda expressions would work:

    auto integral = [](double x)
    {  // Integrates from 0 to x:
       static tanh_sinh<double> integrator;
       static auto f = [](double x) { return 5 * x + 7; };
       return integrator.integrate(f, 0.0, x);
    };
    std::cout << integral(2) << std::endl;
    std::cout << integral(4.5) << std::endl;

I'm not sure what you had in mind with non-scalar arguments, but if you
need to evaluate the above at multiple x values [x_1, x_2.... x_n] then
conceivably you could integrate from

[a, x_0]

[x_1, x_2]

....

[x_n-1, x_n]

and then sum to get the integrals

[a, x_0]

[a, x_1]

....

[a, x_n]

Which may or may not be more efficient.

HTH, John.

>
> I currently have an implementation using GSL_functions which
> explicitly allow the function and parameters to be passed as pointers.
> I am curious if I can do something similar with boost.
>
> Thank you.
>
>
> --
> Anirban Pal
>
>
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users@lists.boost.org
> https://lists.boost.org/mailman/listinfo.cgi/boost-users

--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
https://lists.boost.org/mailman/listinfo.cgi/boost-users


--
Anirban Pal



_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
https://lists.boost.org/mailman/listinfo.cgi/boost-users