การแยกฟังก์ชัน C++ ของตัวแปรหลายตัวสำหรับการรวมพื้นที่สี่เหลี่ยมจัตุรัส

ฉันต้องการรวมตัวเลขเข้ากับ boost::math::quadrature::trapezoidal(g, a, b, 1e-6); ที่นี่ ฉันกำลังรวมฟังก์ชัน g(x) ปัญหาคือว่าผมต้องทำอินทิกรัลสองเท่า นอกจากนี้ ฉันมีตัวแปร 4 ตัวในฟังก์ชันที่ฉันต้องการรวมเข้าด้วยกัน 2 รายการที่ฉันผ่านขณะอินทิเกรต (m,n) และอีก 2 รายการเป็นตัวแปรอินทิเกรต (r,z) นี่คืออินทิกรัลที่ฉันต้องการคำนวณ:

$$ \int_0^b\int_0^af(r,z)\sin{(\frac{n\pi}{a}z)}J_0(\frac{\alpha_{ 0,m}}{b}r)dzdr $$

ฉันเห็นตัวอย่างนี้ ดำเนินการรวมตัวเลข 2 มิติด้วย Boost Cpp และ สังเกตเห็นว่าเขาใช้ฟังก์ชันแลมบ์ดาเพื่อแยกอินทิแกรนด์หลักออกเป็น 2 จนถึงตอนนี้ฉันจัดการสิ่งนี้แล้ว

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;
}

การใช้งานฟังก์ชัน $f(r,z)$ และส่วนที่เหลือของอินทิกรัลมีดังต่อไปนี้

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);
}

โดยปกติแล้ว Initial จะไม่ต้องการพวกมันและตัวแปร n ตัว แต่ในกรณีนี้ ฉันต้องทำการทดสอบบางอย่าง

ปัญหาคือฉันไม่เข้าใจว่าจะแยกฟังก์ชันของฉันเหมือนในตัวอย่างสำหรับปัญหาของฉันและดำเนินการบูรณาการอย่างไร เนื่องจากบูสต์ยอมรับฟังก์ชันตัวแปรเพียง 1 รายการเท่านั้น

กรุณาช่วย


person Carlos Andrés del Valle    schedule 29.04.2021    source แหล่งที่มา
comment
หากต้องการดูว่าเกิดอะไรขึ้น ให้สร้างฟังก์ชันแยกสำหรับแลมบ์ดาทั้งหมด นอกจากนี้ คุณจะขาด m และ n เมื่อคุณคืนค่า f1 จากฟังก์ชันแลมบ์ดา g   -  person Biswajit Banerjee    schedule 29.04.2021
comment
สวัสดี ประเด็นก็คือบูสต์ยอมรับฟังก์ชันตัวแปรเพียง 1 ฟังก์ชันเท่านั้น ดังนั้น g และ f ต้องเป็นเพียง 1 ตัวแปร ไม่รู้ว่าจะทำอย่างไรกับ m และ n   -  person    schedule 29.04.2021
comment
ดูเหมือนคำถามเกี่ยวกับการเขียนโปรแกรมเกี่ยวกับวิธีการส่งพารามิเตอร์ไปยัง lambdas ดังนั้นจึงดูเหมือนนอกประเด็นที่นี่   -  person Federico Poloni    schedule 29.04.2021
comment
@ CarlosAndrésdelValle: คุณไม่จำเป็นต้องเรียกใช้ฟังก์ชัน boost ด้วยสองอาร์กิวเมนต์ เพียงคูณอาร์กิวเมนต์ล่วงหน้าด้วย m หรือ n ก่อนที่คุณจะส่งมันเพื่อเพิ่มพลัง   -  person Biswajit Banerjee    schedule 29.04.2021


คำตอบ (1)


ตามปกติแล้ว แนวคิดพื้นฐานคือการบูรณาการในสองขั้นตอน สำหรับสิ่งนี้ คุณต้องแก้อินทิกรัลด้านในก่อนและสร้างฟังก์ชันหนึ่งมิติขึ้นมา จากนั้นจึงส่งผ่านไปยังตัวอินทิเกรตอีกครั้ง

แลมบ์ดาจะใช้เมื่อใดก็ตามที่คุณต้องการลดฟังก์ชันหลายพารามิเตอร์ให้เหลือฟังก์ชันพารามิเตอร์เดียว ในกรณีนี้ คุณใส่ทั้งหมดที่ไม่ใช่ตัวแปรรวมในการจับภาพแลมบ์ดา

นี่คือรหัสเทียม:

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);
};

คุณอาจไม่จำเป็นต้องเขียนการดักจับแลมบ์ดา กล่าวคือ การจับภาพอ้างอิงด้วย & ก็ใช้ได้เช่นกัน (auto inner_integral = [&](double z){...})

person davidhigh    schedule 29.04.2021
comment
ขอบคุณสำหรับคำตอบ. ฉันมีคำถามคอมไพเลอร์กรีดร้องว่า Missing ; หรือ ก่อน return ครั้งล่าสุด และบอกว่าฟังก์ชันไม่มีคำสั่ง return ฉันจะแก้ปัญหานั้นได้อย่างไร? นั่นอะไร ; ในที่สุด }? - person ; 29.04.2021
comment
ใช่ และมันถูกต้อง ท้ายวงเล็บแลมบ์ดาสุดท้ายก่อนส่งคืน จะต้องเป็น ; - person davidhigh; 30.04.2021