【问题标题】:NumPy complex array and callbacksNumPy 复杂数组和回调
【发布时间】:2016-04-14 01:01:03
【问题描述】:

我想将这个问题How to access arrays passed to ctypes callbacks as numpy arrays? 扩展到复数的情况。

test.py

#!/usr/bin/env python

import numpy as np
import numpy.ctypeslib as npct
import ctypes
import os.path

array_1d_double = npct.ndpointer(dtype=np.complex128, ndim=1, flags='CONTIGUOUS')

callback_func = ctypes.CFUNCTYPE(
    None,            # return
    ctypes.POINTER(np.complex128), # x
    ctypes.c_int     # n
)

libtest = npct.load_library('libtest', os.path.dirname(__file__))
libtest.callback_test.restype = None
libtest.callback_test.argtypes = [array_1d_double, ctypes.c_int, callback_func]


@callback_func
def callback(x, n):
    x = npct.as_array(x, (n,))
    print("x: {0}, n: {1}".format(x[:n], n))


if __name__ == '__main__':
    x = np.array([20, 13, 8, 100, 1, 3], dtype=np.complex128)
    libtest.callback_test(x, x.shape[0], callback)

test.c

#include <complex.h>

typedef void (*callback_t)(
    void* *x,
    int n
);

void callback_test(void** x, int n, callback_t callback) {
    _Complex double* cx = (_Complex double*)x;
        for(int i = 1; i <= 5; i++) {

                for(int j = 0; j < n; j++) {
                        cx[j] = cx[j] / i;
                }

                callback(x, n);
        }
}

给我:

回溯(最近一次通话最后一次):

中的文件“test.py”,第 12 行 ctypes.POINTER(np.complex128), #x
TypeError: type 必须有存储信息

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: python numpy callback


    【解决方案1】:

    ctypes 不能直接处理 numpy 类型。因此“POINTER(np.complex128)”会导致错误。您可以使用 ndpointer 结果作为类型并删除 as_array 中的 shape 参数。这对我有用:

    #!/usr/bin/env python
    
    import numpy as np
    import numpy.ctypeslib as npct
    import ctypes
    import os.path
    
    array_1d_double = npct.ndpointer(dtype=np.complex128, ndim=1, flags='CONTIGUOUS')
    
    callback_func = ctypes.CFUNCTYPE(
        None,            # return
        array_1d_double,
        ctypes.c_int     # n
    )
    
    libtest = npct.load_library('libtest', os.path.dirname(__file__))
    libtest.callback_test.restype = None
    libtest.callback_test.argtypes = [array_1d_double, ctypes.c_int, callback_func]
    
    
    @callback_func
    def callback(x, n):
        x._shape_ = (n,)
        x = npct.as_array(x)
        print("x: {0}, n: {1}".format(x[:n], n))
    
    
    
    if __name__ == '__main__':
        x = np.array([20, 13, 8, 100, 1, 3, 11, 12, 13], dtype=np.complex128)
        libtest.callback_test(x, x.shape[0], callback)
    

    【讨论】:

    • 感谢您的回答。但是,当 shape(6,) 未设置时,这不起作用(所以我不能使用不同的数组大小)。
    • 我添加了一个“hack”来将形状分配给返回的 ndpointer 的私有 shape 属性。我认为应该有一种更清洁的方法来做到这一点,但至少这适用于我的 numpy 版本。
    • 谢谢,这似乎适用于我的应用程序。我不是 NumPy 的专家,你能告诉我使用你的“黑客”有什么危险吗?
    • 一般的 Python 约定是,以单个下划线开头的属性被认为是“私有的”,因此可能会改变它们的语义,甚至在未来消失,而不会在更改日志中注意到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    相关资源
    最近更新 更多