[英]my code is very slow compile when i set large number n. i do not know how to set loops
C ++編譯2D向量的速度非常慢
std::vector< vector<double> > V(n, vector<double> (n));
double sum2=0;
for(int i=0; i<n; i++)
{
double xai=xa1+i*dxa;
double dxr=(double)(xr2-xr1)/n;
double sum1=0;
for(int j=0; j<n; j++){
double xri=xr1+dxr*j;
V[i][j]=fun(xri,xai);
double rect1=V[i][j]*dxr;
sum1+=rect1;
}
double rect2=sum1*dxa;
sum2+=rect2;
}
return sum2;
此代碼集成了2維[(1/2 * pi)* exp(-xr ^ 2/2)* exp(-xa ^ 2/2)]。
該方程的積分在無窮大極限處等於1,因此在c ++中,我們必須增加極限值和n才能得到理論上等於1的結果。
如果我們將牛頓-科茨正交應用於無限積分
,我們需要切除該積分的上下邊界。 積分點的臨界點必須小到可以忽略不計。 您選擇了哪個值?
您的問題的整體是高斯,並且正以這種方式迅速減少,
exp(-10*10/2) ~ 1.93 * 10^(-22)
在目前的整合中可以忽略不計。 因此,如果我們分別將下邊界和上邊界截去-10和+10,並在此范圍內設置足夠的點,則應該得到精確的結果。
使用以下梯形正交,我實際上得到了100x100點的精確結果。 這個正交是最簡單的一個。 我的測試代碼在這里 。
一維整合:
template<typename F>
double integrate_trapezoidal(F func, std::size_t n, double lowerBnd, double upperBnd)
{
if(lowerBnd == upperBnd){
return 0.0;
}
auto integral = 0.0;
auto x = lowerBnd;
const auto dx = (upperBnd - lowerBnd)/n;
auto left = func(x);
for(std::size_t i = 0; i<n; ++i)
{
x += dx;
const auto right = func(x);
integral += (left + right);
left = right;
}
integral *= (0.5*dx);
return integral;
}
二維整合:
template<typename F>
double integrate_trapezoidal_2dim(
F func_2dim,
std::size_t n,
double x_lowerBnd, double x_upperBnd,
double y_lowerBnd, double y_upperBnd)
{
auto func = [&](double x)
{
return integrate_trapezoidal(
std::bind(func_2dim, x, std::placeholders::_1),
n, y_lowerBnd, y_upperBnd);
};
return integrate_trapezoidal(func, n, x_lowerBnd, x_upperBnd);
}
我擔心您設置了有限但很大的上下邊界。 在這種情況下,您需要設置許多點以增加品脫數,范圍為-10 <x <+10。
最后,對於數值積分有各種求積。 如果將函數插入此高斯積分中,則建議使用Hermite正交或快速高斯變換(FGT)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.