【问题标题】:Passing an array from python to C using ctypes, then using that array in Python使用 ctypes 将数组从 python 传递到 C,然后在 Python 中使用该数组
【发布时间】:2020-10-25 13:11:35
【问题描述】:

我正在尝试创建一个histogram of Poisson random generated variables using Python and C。我想使用Python for plottingC for generating. This resulted in the following to codes

Python:

import ctypes
import numpy as np
import matplotlib.pyplot as plt
import time

lam = 5.0
n = 1000000

def generate_poisson(lam, n):
    array = np.zeros(n, dtype= np.int)
    f = ctypes.CDLL('./generate_poisson.so').gen_poisson
    f(ctypes.c_double(lam), ctypes.c_int(n), ctypes.c_void_p(array.ctypes.data))
    return array

start_time = time.time()
array = generate_poisson(lam,n)
print(time.time() - start_time)

plt.hist(array, bins = [0,1,2,3,4,5,6,7,8,9,10,11,12], density = True)
plt.savefig('fig.png')
print(array)

C:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

double get_random() { return ((double)rand() / (double)RAND_MAX); }

int poisson_random(double lam){
    int X;
    double prod, U, explam;

    explam = exp(-lam);
    X = 0;
    prod = 1.0;
    while (1){
        U = get_random();
        prod *= U;
        if (prod > explam){
            X+=1;
        }
        else {
            return X;
        }
    }
}

void gen_poisson(double lam, int n, void * arrayv)
{
    int * array = (int *) arrayv;
    int index = 0;
    srand(time(NULL));

    for (int i =0; i<n; i++, index++){
        //printf("before %d\n", array[i]);
        array[index++] = poisson_random(lam);
        //printf("after %d\n", array[i]);
    }
}

gen_poisson() 的 for 循环中,理解为什么会这样工作,或者至少看起来可以正常工作的问题发生在。不知何故,使用array[index++] 而不是array[index] 会产生正确的直方图。但我真的不明白为什么会这样。当 for 循环更改为

时,该代码似乎也可以工作
for (int i =0; i<2*n; i++){
        //printf("before %d\n", array[i]);
        array[i++] = poisson_random(lam);
        //printf("after %d\n", array[i]);
}

有人可以解释为什么在这种情况下循环必须增加两次吗?我刚开始用 C 编程,而我有一些 Python 经验。所以假设罪魁祸首是我对C缺乏了解。提前谢谢你

【问题讨论】:

  • 您能否澄清在不增加 index 的情况下 not 工作的程度?标题和标签提到了 Cython,这通常使编写正确的代码变得容易得多,但问题似乎没有包括它——你真的使用 Cython 吗?它与您的问题的相关程度如何?
  • 你有一个 C 数组 long,而不是 int
  • 我实际上是指 ctypes 而不是 Cython。我编辑了帖子,我的错
  • 你的 Python 代码声明了一个 c_int 的 np.array ... 所以在 C 代码中更改为 long* 对我来说毫无意义。您的代码按原样工作,int 数组和 int* 具有正确的索引。

标签: python arrays c ctypes


【解决方案1】:

gen_poisson改成:

void gen_poisson(double lam, int n, void * arrayv)
{
    long * array = (long *) arrayv;
    srand(time(NULL));
    for (int i =0; i<n; i++){
        array[i] = poisson_random(lam);
    }
}

解决问题。问题正如将数组声明为 int * 而不是 long * 所指出的那样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多