【问题标题】:Python Tuple to Cython StructPython 元组到 Cython 结构
【发布时间】:2014-02-27 20:10:57
【问题描述】:

Scipy splprep(样条准备)产生一个 Tuple tckp

tckp : tuple (t,c,k) 一个包含节点向量的元组, B样条系数,以及样条的次数。

tckp = [array[double,double ,..,double], 
       [array[double,double ,..,double],          
        array[double,double ,..... ,double], 
        array[double,double ,..... ,double]], int]                                        

如何构建和填充等效的 Cython 结构以便能够使用

Cython 中的 splev(样条求值)

【问题讨论】:

  • 您打算如何调用 splev?你打算使用内置于 SciPy 中的那个,还是使用相应 fortran library 中的 splev 函数的一些包装器?调用过程将取决于您要如何调用它。
  • 第一步是 SciPy Wrapper - 但我担心需要更多优化。
  • 好的,SciPy 包装器实际上只是 Fortran 例程的 Python 包装器。您需要在 Cython 中调用它,就像在 Python 中调用它一样。这将是一个 Python 函数调用,并且仍然会有相应的开销。如果您需要避免通过 Python 进行函数调用的开销,则必须为 Fortran 例程获取某种包装器。我敢打赌fortran90.org/src/best-practices.html#interfacing-with-c 显示的方法将是一个很好的起点。您可以尝试直接从 Scipy 公开函数指针。
  • 然后起点将我们带到stackoverflow.com/tags/fortran-iso-c-binding/info 和20 年前我最后一次阅读和潦草的fortran
  • 您可以尝试使用类似this question 的答案,但这也很棘手。我也不完全确定它是否适用于样条函数。

标签: python scipy tuples cython


【解决方案1】:

正如 cmets 中所讨论的,这取决于您如何将 tckp 传递给其他函数。存储此信息并传递给其他函数的一种方法是使用struct

在下面的示例中,您使用structtckp 列表传递给cdef 函数,该函数将void * 作为输入,模拟C 函数...此示例函数将1 添加到所有数组假设int0 是数组的大小。

import numpy as np
cimport numpy as np

cdef struct type_tckp_struct:
    double *array0
    double *array1
    double *array2
    double *array3
    int *int0

def main():
    cdef type_tckp_struct tckp_struct
    cdef np.ndarray[np.float64_t, ndim=1] barray0, barray1, barray2, barray3
    cdef int bint

    tckp = [np.arange(1,11).astype(np.float64),
            2*np.arange(1,11).astype(np.float64),
            3*np.arange(1,11).astype(np.float64),
            4*np.arange(1,11).astype(np.float64), 10]
    barray0 = tckp[0]
    barray1 = tckp[1]
    barray2 = tckp[2]
    barray3 = tckp[3]
    bint = tckp[4]
    tckp_struct.array0 = &barray0[0]
    tckp_struct.array1 = &barray1[0]
    tckp_struct.array2 = &barray2[0]
    tckp_struct.array3 = &barray3[0]
    tckp_struct.int0 = &bint

    intern_func(&tckp_struct)

cdef void intern_func(void *args):
    cdef type_tckp_struct *args_in=<type_tckp_struct *>args
    cdef double *array0
    cdef double *array1
    cdef double *array2
    cdef double *array3
    cdef int int0, i
    array0 = args_in.array0
    array1 = args_in.array1
    array2 = args_in.array2
    array3 = args_in.array3
    int0 = args_in.int0[0]

    for i in range(int0):
        array0[i] += 1
        array1[i] += 1
        array2[i] += 1
        array3[i] += 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 2015-12-25
    • 2017-04-23
    相关资源
    最近更新 更多