Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用类方法作为GSL QAGS的被积函数_Python_Function_Class_Methods_Cython - Fatal编程技术网

Python 使用类方法作为GSL QAGS的被积函数

Python 使用类方法作为GSL QAGS的被积函数,python,function,class,methods,cython,Python,Function,Class,Methods,Cython,我想用一个类的成员函数作为gsl_函数的全局函数,但我不知道该怎么做。由于我现在只了解C的基本知识,我知道我必须将类实例(被积函数)发送到void参数,但从技术上讲,我无法在cython中对其进行编码,这是一个cython示例 from cython_gsl cimport * ctypedef double * double_ptr ctypedef void * void_ptr cdef double foo(double x, void * params) nogil: cd

我想用一个类的成员函数作为gsl_函数的全局函数,但我不知道该怎么做。由于我现在只了解C的基本知识,我知道我必须将类实例(被积函数)发送到void参数,但从技术上讲,我无法在
cython
中对其进行编码,这是一个cython示例

from cython_gsl cimport *

ctypedef double * double_ptr
ctypedef void * void_ptr

cdef double foo(double x, void * params) nogil:
    cdef double alpha, f
    alpha = (<double_ptr> params)[0]
    f = log(alpha*x) / sqrt(x)
    return f


def main():
    cdef gsl_integration_workspace * w
    cdef double result, error, expected, alpha
    w = gsl_integration_workspace_alloc (1000)

    expected = -4.0
    alpha = 1

    cdef gsl_function F
    F.function = &foo
    F.params = &alpha

    gsl_integration_qags (&F, 0, 1, 0, 1e-7, 1000, w, &result, &error)
    print "result          = % .18f\n" % result
    print "estimated error          = % .18f\n" % error
来自cython\u gsl cimport的
*
ctypedef double*double\u ptr
ctypedef void*void\u ptr
cdef双foo(双x,无效*参数)编号:
双α,f
alpha=(参数)[0]
f=对数(α*x)/sqrt(x)
返回f
def main():
cdef gsl_集成_工作区*w
cdef双重结果,错误,预期,alpha
w=gsl\u集成\u工作空间\u分配(1000)
预期值=-4.0
α=1
cdef gsl_函数F
F.function=&foo
F.params=&alpha
gsl_集成_质量保证(&F、0、1、0、1e-7、1000、w、结果和错误)
打印“结果=%.18f\n”%result
打印“估计错误=%.18f\n”%error
假设我有以下课程:

from math import *
cdef class Foo(object):
    def __init__(self, double a=1.2, double b=0.6):
        self.a = a
        self.b = b
    def _integrand(self,double x):
         cdef double self.a = (<double_ptr> params)[0]
         cdef double self.b = (<double_ptr> params)[1]
         return self.a*log(x)+self.b/x**3
    def whole(self, double upper_limit=10,double lower_limit=0):
        cdef gsl_integration_workspace * w
        cdef double result, error, expected, alpha
        w = gsl_integration_workspace_alloc (1000)

        expected = -4.0
        params[0] = self.a
        params[1] = self.b

        cdef gsl_function F
        F.function = &self._integrand
        F.params = params

        gsl_integration_qags (&F, lower_limit,upper_limit , 0, 1e-7, 1000, w, &result, &error)
        return result,error
从数学导入*
cdef类Foo(对象):
定义初始值(自,双a=1.2,双b=0.6):
self.a=a
self.b=b
def_被积函数(自,双x):
cdef double self.a=(参数)[0]
cdef double self.b=(参数)[1]
返回self.a*log(x)+self.b/x**3
def整体(自身,双上限=10,双下限=0):
cdef gsl_集成_工作区*w
cdef双重结果,错误,预期,alpha
w=gsl\u集成\u工作空间\u分配(1000)
预期值=-4.0
参数[0]=self.a
参数[1]=self.b
cdef gsl_函数F
F.函数=&self.\u被积函数
F.params=params
gsl_集成_qags(&F、下限、上限、0、1e-7、1000、w、结果和错误)
返回结果,错误

如何将
Foo.\u被积函数
转换为可由
gsl
使用的全局函数?

只需取出“self”并将a&b添加到其调用签名中,然后删除代码即可

    def _integrand(x, a, b):
        return a*log(x)+b/x**3

在Python中,您可以使用
functools.partial
像函数预定义
self
参数一样传递方法:

from functools import partial

foo = Foo()
integrand_func = partial(Foo._integrand, foo)
但是你不能在C中定义这样一个偏函数。因此,我将被积函数外部化,并将其定义为类的一个参数,而不是一个额外的方法。请注意,这类似于使用静态方法,但是。另一个重要提示是使用
log
form
math.h
。请参见下面的原型:

#cython: wraparound=False
#cython: boundscheck=False
#cython: cdivision=True
#cython: nonecheck=False
cdef extern from "math.h":
    double log(double x) nogil

ctypedef double (*function)(double x, void *params)

cdef struct integrandFoo_p:
    double *a
    double *b

cdef struct gsl_function:
    function function
    void *params

cdef double integrandFoo(double x, void *params):
    cdef integrandFoo_p *p=<integrandFoo_p *>params
    cdef double a, b
    a = p.a[0]
    b = p.b[0]
    return a*log(x)+b/(x*x*x)

cdef void trapzd(gsl_function *F, double lower_limit, double upper_limit,
                 int num, double *result, double *error):
    cdef int i
    cdef double x
    f = F[0].function
    p = F[0].params
    result[0] = 0.
    for i in range(num+1):
        x = lower_limit + (upper_limit - lower_limit)*i/num
        if i==0 or i==num:
            result[0] += f(x, p)*0.5
        else:
            result[0] += f(x, p)

    error[0] = 0.

cdef class Foo(object):
    cdef double a
    cdef double b
    cdef double result
    cdef double error
    cdef function f
    def __init__(self):
        self.a = 1.2
        self.b = 0.6
        self.f = <function>integrandFoo
    cdef void integrate(self, double lower_limit=1, double upper_limit=10):
        #cdef gsl_integration_workspace * w
        cdef double result, error, expected, alpha
        cdef integrandFoo_p p
        cdef gsl_function F

        #w = gsl_integration_workspace_alloc(1000)
        p.a = &self.a
        p.b = &self.b
        expected = -4.0

        F.function = self.f
        F.params = &p

        trapzd(&F, lower_limit, upper_limit, 1000, &self.result, &self.error)
        #gsl_integration_qags(&F, lower_limit, upper_limit, 0, 1e-7,
                             #1000, w, &result, &error)
def main():
    foo = Foo()
    print 'HERE', foo.result, foo.error
    foo.integrate()
    print 'HERE', foo.result, foo.error
#cython:wrapparound=False
#cython:boundscheck=False
#cython:cdivision=True
#cython:nonecheck=False
“math.h”中的cdef外部变量:
双对数(双x)nogil
ctypedef double(*函数)(双x,无效*参数)
cdef结构集成文件:
双倍*a
双倍*b
cdef结构gsl_函数:
功能
void*params
cdef double integrandFoo(双x,void*params):
cdef integrandFoo_p*p=params
cdef双a,b
a=p.a[0]
b=p.b[0]
返回a*log(x)+b/(x*x*x)
cdef void trapzd(gsl_函数*F,双下限,双上限,
int num,double*结果,double*错误):
cdef int i
cdef双x
f=f[0]。函数
p=F[0]。参数
结果[0]=0。
对于范围内的i(num+1):
x=下限+(上限-下限)*i/num
如果i==0或i==num:
结果[0]+=f(x,p)*0.5
其他:
结果[0]+=f(x,p)
错误[0]=0。
cdef类Foo(对象):
cdef双a
cdef双b
cdef双重结果
双误
cdef函数
定义初始化(自):
self.a=1.2
self.b=0.6
self.f=integrandFoo
cdef无效积分(自、双下限=1、双上限=10):
#cdef gsl_集成_工作区*w
cdef双重结果,错误,预期,alpha
cdef集成程序
cdef gsl_函数F
#w=gsl\u集成\u工作空间\u分配(1000)
p、 a=&self.a
p、 b=&self.b
预期值=-4.0
函数=self.F
F.params=&p
trapzd(&F,下限,上限,1000,&self.result,&self.error)
#gsl\U集成\U qags(&F,下限,上限,0,1e-7,
#1000、w、结果和错误)
def main():
foo=foo()
打印“此处”,foo.result,foo.error
foo.integrate()
打印“此处”,foo.result,foo.error

一个问题:最后一行不应该说
return self.a*log(x)+self.b/x**3
?在绑定到的类的实例的上下文之外,您想要创建全局的特定方法没有任何意义。它取决于
a
b
,两者都是实例类属性。“你为什么要做你要做的事?”阿鲁伊斯丹特,因为这只是我更大问题的一个例子。我想在一个类中使用这个积分,但我不知道该怎么做。@Saullo如果我想在类中添加一个实例来计算给定函数的积分,我该怎么做呢?
@staticmethod
是否有助于使被积函数独立于整个类,或者使一个通用的
被积函数
在类外没有一个明确的给定函数,并且在类中被调用以获取类参数作为输入可以解决这个问题Dalekmy的问题是,我需要在类内定义被积函数,因为不是在本例中,而是我需要使用类内的其他瞬间来构建被积函数。然而,仍然有两个问题我无法用cython构建您的答案。例如,第一个错误
无法将类型“integrandFoo\u p”分配给“integrandFoo\u p*”
,第二个错误是
self.f=integrandFoo
它引发的
无法将类型“double(double,void*)”分配给“function”
,然后对于
p.a=&self.a
我得到了这个错误
无法获取Python的地址