Boost logo

Boost Users :

From: Anirban Pal (anirban.pal.iitkgp_at_[hidden])
Date: 2020-08-21 01:00:22


Thank you John and Kila.

On Thu, 20 Aug 2020 at 00:42, kila suelika via Boost-users <
boost-users_at_[hidden]> wrote:

> 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_at_[hidden]> 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_at_[hidden]> 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_at_[hidden]
>>> > 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_at_[hidden]
>>> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>>>
>>
>>
>> --
>> Anirban Pal
>>
>>
>>
>> _______________________________________________
>> Boost-users mailing list
>> Boost-users_at_[hidden]
>> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>

-- 
Anirban Pal


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net