`
chinamming
  • 浏览: 151310 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

GSL-蒙特卡洛积分

 
阅读更多

GSL-蒙特卡洛积分 TR:SAN E:VISUALSAN@YAHOO.CN 2011.3.23

---------------------------------------------------------------------------

Gsl中包含有计算N重积分的蒙特卡洛方法,不过只能计算积分上下限确定的多重积分,对于上下限带有参数的积分无能为力,表达式如下:

三种蒙特卡洛积分实现方法分别定义在头文件:

#include <gsl/gsl_monte_miser.h>

#include <gsl/gsl_monte_plain.h>

#include <gsl/gsl_monte_vegas.h>

每组方法的计算思路是一样的:生成控制变量、初始化控制变量、计算积分、释放控制变量。每种方法都将用到随机数产生器。其中需要用户自定义被积分函数:

double (*f)(double * x_array, size_t dim, void * params);

其中x是积分变量数组,dim为积分变量个数,parms为额外传递的参数

对于二次函数f(x,y)=ax2+bxy+cy2,当a=3,b=2,c=1时,下面将定义目标函数:

复制代码
struct my_par
{
double a,b,c;
};
double my_f(double* x_array, size_t dim, void*params)
{
my_par
*mp=(my_par*)params;
if(dim!=2)
{
fprintf(stderr,
"dim!=2");
abort();
}
return x_array[0]*x_array[0]*mp->a+
x_array[
0]*x_array[1]*mp->b+
x_array[
1]*x_array[1]*mp->c;
}

void test_monte()
{
my_par par
={3,2,1};
gsl_monte_function f;
f.dim
=2;
f.f
=my_f;
f.
params=&par;

}
复制代码

下面介绍用法:

  1. plainmonte carlo

包含头文件:#include <gsl/gsl_monte_plain.h>

使用步骤:

(1) gsl_monte_plain_state* gsl_monte_plain_alloc(size_t dim);

申请一个计算dim重积分的gsl_monte_plain_state类型控制变量

(2) int gsl_monte_plain_init(gsl_monte_plain_state* state);

初始化控制变量

(3) int gsl_monte_plain_integrate (const gsl_monte_function * f,

const double xl[], const double xu[],

const size_t dim,

const size_t calls,

gsl_rng * r,

gsl_monte_plain_state * state,

double *result, double *abserr);

计算monte carlo积分,参数意义如下:

:f->被积分函数

:xl->积分下限数组,共有dim个

:xu->积分上限数组,共有dim个

:dim->积分重数

:calls->目标函数被调用次数,比如500000

:r->随机数产生器,比如r= gsl_rng_default

:state->状态空间,由gsl_monte_plain_alloc申请

:result->计算结果

:abserr->绝对误差

例子:计算多重积分

复制代码
#include <iostream>
#include
<time.h>
#include
<gsl/gsl_rng.h>
#include
<gsl/gsl_integration.h>
#include
<gsl/gsl_monte.h>
#include
<gsl/gsl_monte_miser.h>
#include
<gsl/gsl_monte_plain.h>
#include
<gsl/gsl_monte_vegas.h>
usingnamespace std;
//visualsan@yahoo.cn SAN NUAA 2011.3.23
struct my_par
{
double a,b,c;
};
double my_f(double* x_array, size_t dim, void*params)
{
my_par
*mp=(my_par*)params;
if(dim!=2)
{
fprintf(stderr,
"dim!=2");
abort();
}
double v= x_array[0]*x_array[0]*mp->a+
x_array[
0]*x_array[1]*mp->b+
x_array[
1]*x_array[1]*mp->c;

return exp(-1/v)/v;
}

void test_monte()
{
my_par par
={3,2,1};
gsl_monte_function f;
f.dim
=2;
f.f
=my_f;
f.
params=&par;

int calls=500000;
double xl[]={0,0},xu[]={3.14,3.14};
double result,er;
gsl_monte_plain_state
*ps=gsl_monte_plain_alloc(2);
const gsl_rng_type*tp=gsl_rng_minstd;
gsl_rng
*pr=gsl_rng_alloc(tp);
gsl_monte_plain_init(ps);
gsl_monte_plain_integrate(
&f,
xl,xu,
2,calls,
pr,ps,
&result,&er);


cout
<<result<<endl;//->0.913118
cout<<er<<endl; //->0.0011711
/*matlab cmd:
fun = @(x,y) exp(-1./(3.*x.*x+2.*x.*y+y.*y))./( 3.*x.*x+2.*x.*y+y.*y );
quad2d(fun,0,3.14,0,3.14)
ans=0.913889482268682
*/

}
void main()
{
test_monte();
}


复制代码
2. miser monte carlo

包含头文件:#include <gsl/gsl_monte_ miser.h>

  1. gsl_monte_miser_state* gsl_monte_miser_alloc(size_t dim);申请计算dim重积分的控制变量
  2. int gsl_monte_miser_init(gsl_monte_miser_state* state);初始化积分控制变量
  3. 积分函数:

int gsl_monte_miser_integrate(gsl_monte_function * f,

const double xl[], const double xh[],

size_t dim, size_t calls,

gsl_rng *r,

gsl_monte_miser_state* state,

double *result, double *abserr);

4.void gsl_monte_miser_free(gsl_monte_miser_state* state);释放控制变量

miser carlo算法有几个参数需要设置,这些参数定义在gsl_monte_miser_state。

estimate_frac:这个参数在方差计算的递归调用过程中,指明每次函数调用次数占可用函数次数的百分比,默认值为0.1

min_calls:这个参数指明每次方差评估过程中函数调用的最小次数,如果申请函数调用次数n小于min_calls,则n=min_calls。min_calls默认值为16*dim.

min_calls_per_bisection:对分步骤中,函数调用的最小次数,默认值16* min_calls

alpha:指定两个子区域的方差如何组合,默认值为2

Dither:引入变异率,打破被积函数在积分区间的对称性。默认为0,当需要引入时,建议取值0.1

3.vegasmonte carlo

包含头文件gsl_monte_vegas.h

使用步骤:

1.)gsl_monte_vegas_state* gsl_monte_vegas_alloc(size_t dim);申请一个dim重积分的控制变量

2.)int gsl_monte_vegas_init(gsl_monte_vegas_state* state);初始化控制变量

3.)int gsl_monte_vegas_integrate(gsl_monte_function * f,

double xl[], double xu[],

size_t dim, size_t calls,

gsl_rng * r,

gsl_monte_vegas_state *state,

double* result, double* abserr);

4.)void gsl_monte_vegas_free (gsl_monte_vegas_state* state);释放控制变量

下面这个例子是GSL手册上的例子:

计算积分

复制代码
#include <iostream>
#include
<time.h>
#include
<gsl/gsl_math.h>
#include
<gsl/gsl_monte_miser.h>
#include
<gsl/gsl_monte_plain.h>
#include
<gsl/gsl_monte_vegas.h>


usingnamespace std;
//e: visualsan@yahoo.cn tr:SAN ad:NUAA t:2011
constdouble exact=1.3932039296;
double my_f(double* k, size_t dim, void*params)
{
double A =1.0/ ( M_PI * M_PI * M_PI );
return A / ( 1.0- cos(k[0]) * cos(k[1]) * cos(k[2]) );
}
void disp_r(char*t,double r,double er,double ct)
{
printf(
"%s----------------------t=%.1fms \n",t,ct);
printf(
"result=%.6f\n",r);
printf(
"sigma=%.6f\n",er);
printf(
"exact=%.6f\n",exact);
printf(
"error=%.6f = %.1g sigma\n",r-exact,fabs(exact-r) / er);
}
void main()
{
cout
<<"monte carlo sample (visualsan@yahoo.cn tr:SAN )\n";
clock_t t1;
gsl_monte_function f;
f.dim
=3;
f.f
=my_f;


int calls=500000;
double xl[]={0,0,0},xu[]={M_PI,M_PI,M_PI};
double result,er;

gsl_rng_env_setup();
const gsl_rng_type*tp=gsl_rng_minstd;
gsl_rng
*pr=gsl_rng_alloc(tp);



//plain
t1=clock();
gsl_monte_plain_state
*ps=gsl_monte_plain_alloc(3);
gsl_monte_plain_init(ps);
gsl_monte_plain_integrate(
&f,
xl,xu,
3,calls,
pr,ps,
&result,&er);
disp_r(
"plain",result,er, (double)(clock()-t1) );
gsl_monte_plain_free(ps);

//miser
t1=clock();
gsl_monte_miser_state
*pm=gsl_monte_miser_alloc(3);
gsl_monte_miser_init(pm);
gsl_monte_miser_integrate(
&f,
xl,xu,
3,calls,
pr,pm,
&result,&er);
disp_r(
"miser",result,er,(double)(clock()-t1));
gsl_monte_miser_free(pm);

//vegas
t1=clock();
gsl_monte_vegas_state
*pv=gsl_monte_vegas_alloc(3);
gsl_monte_vegas_init(pv);
gsl_monte_vegas_integrate(
&f,
xl,xu,
3,10000,
pr,pv,
&result,&er);
disp_r(
"vegas warm-up",result,er,(double)(clock()-t1));

printf(
"convering......\n");
t1
=clock();
do
{
gsl_monte_vegas_integrate(
&f,
xl,xu,
3,calls/5,
pr,pv,
&result,&er);
printf(
"result=%.6f,sigma=%.6f,chisq/dof=%.1f\n",result,er,pv->chisq);
}
while (fabs(pv->chisq-1.0)>0.5);
gsl_monte_vegas_free(pv);
disp_r(
"vegas final",result,er,(double)(clock()-t1));

}
复制代码

-------------------------------------------------------------------------------------------------

SAN VISUALSAN@YAHOO.CN 2011.3.23 NUAA

分享到:
评论

相关推荐

    gsl-1.8科学计算库

    2. **数值积分**:GSL库包含了多种数值积分方法,如梯形法、辛普森法、高斯积分等,适用于处理各种函数的定积分和重积分问题。这些算法经过精心设计,能够在保持精度的同时,有效提高计算效率。 3. **微分方程求解*...

    gsl-1.4.tar_gsl_

    2. **数值积分**:GSL支持多种数值积分方法,如高斯积分、辛普森法则、梯形法则等,用于解决无法解析求解的积分问题。 3. **微分方程**:对于常微分方程(ODE)和偏微分方程(PDE),GSL提供了若干数值解法,如欧拉...

    gsl-1.8.rar

    6. **微积分**:支持数值积分和微分,可以用于解决复杂的积分问题和求解偏微分方程。 7. **信号处理**:提供傅立叶变换、滤波器设计和信号分析工具,适合音频、图像和其他时间序列数据的处理。 安装和使用GSL 1.8...

    gsl.zip_gsl 静态_gsl- zip_gsl库 lib_gsl库计算积分_gsl静态库

    4. **随机数生成**:GSL包含了各种随机数分布(均匀、正态、泊松等)的生成器,以及随机数序列的统计测试,这对于统计模拟和蒙特卡洛方法非常重要。 5. **插值和样条函数**:GSL库提供了数据点的线性、多项式、立方...

    gsl-1.12.tar.gz

    GSL库提供了大量的数学函数,涵盖了线性代数、数值积分、插值、随机数生成、统计分析、微积分、傅里叶变换等多个方面。这些函数可以帮助程序员快速构建科学计算相关的应用程序,无需从零开始编写底层算法。GSL支持...

    gsl-ref.rar_gsl

    GSL,全称为GNU Scientific Library,是由C语言编写的,提供了一系列高级数值算法,涵盖了线性代数、傅立叶变换、随机数生成、插值、积分、常微分方程求解等多个领域。这个库是免费且开放源代码的,遵循GPL许可证,...

    gsl-ref.pdf.zip_gsl_ref

    3. **积分与微分**:GSL支持数值积分(高斯积分、辛普森法则、梯形法则等)和微分方程求解,对于解决复杂的数学问题至关重要。 4. **随机数生成**:GSL提供了一系列随机数生成器,包括均匀分布、正态分布、泊松分布...

    已编译gsl-2.4_Win64

    4. **随机数生成**:包含多种随机数分布,如均匀、正态、泊松等,以及种子设置和随机数序列生成器,支持统计模拟和蒙特卡洛方法。 5. **常微分方程**:提供了数值解常微分方程的算法,如欧拉法、龙格-库塔方法等,...

    gsl的一些老版本库

    3. **随机数生成**:GSL支持多种分布(如均匀、正态、泊松等)的随机数生成,这对于统计模拟和蒙特卡洛方法至关重要。 4. **插值和样条**:提供了多项式插值、样条插值和立方体插值等,便于数据的平滑处理。 5. **...

    gsl库--强大的数学库

    3. **随机数生成**:GSL提供了多种随机数生成器,支持均匀分布、正态分布、泊松分布等常见概率分布,适用于统计模拟和蒙特卡洛方法。 4. **插值**:GSL库包含了多项式插值、样条插值等算法,可以用来估算未知数据点...

    GSL库在vs2005中的移植.doc

    - **蒙特卡洛积分**:通过随机采样进行积分估计。 - **模拟退火算法**:用于全局优化问题。 - **微分方程求解**:包括欧拉法、龙格-库塔法等数值方法。 - **内插与外推**:实现多项式内插、样条内插等技术。 - **...

    GSL( GNU Scientific Library) 2.5 含源代码及CMake工程 和已编译库dll,lib

    1. **数学函数**:GSL包含了广泛的数学函数,如特殊函数(伽马函数、贝塞尔函数等)、线性代数运算(矩阵操作、特征值和特征向量求解)、微积分(数值积分、微分方程求解)等。 2. **随机数生成**:GSL提供了多种...

    GNU Scientific Library (GSL)C++科学计算库

    2. **数值积分**:对于一维和多维的积分问题,GSL提供了多种数值积分方法,如高斯-辛普森法则、高斯-克吕格尔法则和蒙特卡洛积分。 3. **插值**:支持多项式插值、样条插值和立方体样条插值,帮助用户找到数据之间...

    计算多重积分的蒙特卡罗方法与数论网格法

    ### 计算多重积分的蒙特卡罗方法与数论网格法 在现代科学与工程领域,计算多重积分是一项至关重要的任务。这类积分在解决实际问题时极为常见,尤其是在求解复杂的物理、化学及工程问题时更为关键。本文将详细介绍两...

    GSL.rar_gsl_gsl文档

    2. **数值积分**:包含多种数值积分方法,如梯形法则、辛普森法则和高斯积分,可用于一维、二维及多维积分的计算。 3. **微分方程**:支持常微分方程(ODE)和偏微分方程(PDE)的数值解法,包括欧拉法、龙格-库塔...

    GNU Scientific Library

    对于偏微分方程(PDE),虽然GSL本身没有直接的求解器,但它提供的数值积分和微分函数可以作为构建自定义PDE求解器的基础。 除了线性代数和微分方程,GSL还包括统计分析、随机数生成、傅立叶变换、特殊函数(如...

    GNU Scientific Library (gsl) Window环境已编译(含lib,dll)

    2. **微积分**:包含了一整套微积分工具,如数值积分、导数和微分方程的求解。这对于物理模拟、工程计算和统计建模等应用非常实用。 3. **常微分方程**:提供了数值方法来解决常微分方程(ODE)系统,包括欧拉方法、...

    GNU Scientific Library Documemt

    2. 随机数生成:GSL 包含多种随机数生成器,如均匀分布、正态分布、泊松分布等,满足各种统计模拟和蒙特卡洛方法的需求。 3. 插值与拟合:GSL 提供了一套完整的插值工具,如线性插值、多项式插值、样条插值等,可以...

    常用数值算法--C语言 (2)_常用数值计算-c语言_

    对于更复杂的函数,可以通过高斯积分或蒙特卡洛方法来求解。 3. **微分方程**:数值解微分方程是数值计算中的另一个关键领域。Euler方法、龙格-库塔方法(Runge-Kutta)家族,以及隐式和显式差分方法都是解决初值...

Global site tag (gtag.js) - Google Analytics