朱莉娅:调用GSL函数

时间:2015-06-11 10:09:06

标签: c julia gsl scientific-computing

我试图使用GSL数值积分函数QNG在Julia中集成一个简单的函数。 C中函数的形式为

int gsl_integration_qng (const gsl_function * f, double a, double b,
 double epsabs, double epsrel, double * result, double * abserr, size_t * neval)

我正在尝试执行以下集成

f(x) = x^2
a, b, epsabs, epsrel = 0.0, 1.0, 1.0e-2, 1.0e-2
result, abserr = 0.0, 0.0
neval =  0x123456789abcdef
0x0123456789abcdef
t = ccall( (:gsl_integration_qng, "libgsl"), Int32, 
(Ptr{Void}, Float64, Float64, Float64, Float64, Ptr{Float64}, Ptr{Float64},Csize_t), 
  &f, a, b, epsabs, epsrel, &result, &abserr, neval)

我感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

I wrote a blog post awhile ago on how to do this关于不同的GSL集成函数。

它的要点是:

定义参数化类型函数

function integrand{T,T2,T3}(x::T,dim::T2,params::T3)
  A = 1.0 / (pi * pi * pi)
  return A / (1.0 - cos(unsafe_load(x,1))*cos(unsafe_load(x,2))*cos(unsafe_load(x,3)))::Cdouble
end

然后获取指针

integrand_c = cfunction(integrand,Cdouble,(Ptr{Cdouble},Ptr{Cdouble},Ptr{Cdouble}))

然后ccall GSL函数,函数指针作为参数之一。在我的例子中:

ccall((:monte_carlo_integrate,"/home/crackauc/Public/libMonte.so"),Int32,(Ptr{Void},Ptr{Cdouble},Ptr{Cdouble},Int32,Int32,Ptr{Cdouble},Ptr{Cdouble},Csize_t),integrand_c,x,y,mode,dim,xl,xu,calls)

答案 1 :(得分:0)

经过一番思考并查看现有的GSL功能后,我得到了这个功能。

type gsl_function
    function_::Ptr{Void}
    params::Ptr{Void}
end

function function_callback(x::Cdouble, f_::Ptr{Void})
    f = unsafe_pointer_to_objref(f_)::Function
    convert(Cdouble, f(x))::Cdouble
end

const function_callback_ptr = cfunction(function_callback, Cdouble, (Cdouble, Ptr{Void}))

function integration_qng(f,a,b,epsrel,epsabs)
  result = convert(Ptr{Cdouble}, Array(Cdouble, 1))
  abserr = convert(Ptr{Cdouble}, Array(Cdouble, 1))
  neval = convert(Ptr{Csize_t}, Array(Csize_t, 1))
  t = ccall( (:gsl_integration_qng, :libgsl), Cint, (Ptr{gsl_function}, Cdouble, Cdouble, Cdouble, Cdouble, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Csize_t}), 
  &gsl_function(function_callback_ptr, pointer_from_objref(f)), a, b, epsabs, epsrel, result, abserr, neval )
  return unsafe_load(result)
end

f(x) = x^2
a = 0
b = 1
epsabs = 0
epsrel = 1e-2

println(integration_qng(f,a,b,epsrel,epsabs))

另请参阅此处http://julialang.org/blog/2013/05/callback/,了解一位比我更有资格的人讨论这类事情。