简体   繁体   English

使用 ctypes 将数组从 python 传递到 C,然后在 Python 中使用该数组

[英]Passing an array from python to C using ctypes, then using that array in Python

I am trying to make a histogram of Poisson random generated variables using Python and C .我正在尝试histogram of Poisson random generated variables using Python and C I wanted to use Python for plotting and C for generating. This resulted in the following to codes我想使用Python for plotting ,使用 C C for generating. This resulted in the following to codes C for generating. This resulted in the following to codes

Python: 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: 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]);
    }
}

The problem understanding why this works, or at least it seems to work correctly, occurs inside the for loop in gen_poisson() .gen_poisson()的 for 循环内,理解为什么会这样工作,或者至少它似乎能正常工作的问题。 Somehow using array[index++] instead of array[index] results in a correct histogram.以某种方式使用array[index++]而不是array[index]会产生正确的直方图。 But I dont really understand why this has to be the case.但我真的不明白为什么会这样。 The code also seems to work when the for loop is changed to当 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]);
}

Can someone explain why in this case the loop has to be incremented twice?有人可以解释为什么在这种情况下循环必须递增两次吗? I just started programming in C while I have some experience in Python. So assume the culprit is my lack of understanding about C. Thank you in advance我刚开始在 C 编程,而我在 Python 有一些经验。所以假设罪魁祸首是我对 C 缺乏了解。提前谢谢你

Changing the gen_poisson into: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);
    }
}

solves the problem.解决了问题。 The problem was as pointed out with declaring the array as int * instead of long * .正如将数组声明为int *而不是long *所指出的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM