如何在ufunc中使用numpy的随机数生成器?

时间:2019-09-09 14:43:26

标签: python numpy numpy-ufunc numpy-random

基本上,我有一个需要一些随机性的ufunc。为了使ufunc尽可能地可重现,我想使用numpy的随机数生成器。基本上是因为这样设置种子会更直观。

但是我找不到numpy.random C-API的文档(它有一个吗?)。

我当前的方法如下:

#include <numpy/random.h> // does not exist
...

static void
ufunc_M( char ** args
       , npy_intp * dimensions
       , npy_intp * steps
       , void * data)
{
    basic_gate_argument_t argument = *((basic_gate_argument_t *) data);
    PYQCS_GATE_GENERIC_SETUP;
    npy_intp i;


    npy_double amplitude_1 = 0;

    for(i = 0; i < ndim; i++)
    {
        if(i & (1 << argument.act))
        {
            amplitude_1 += qm_in[i].real * qm_in[i].real;
            amplitude_1 += qm_in[i].imag * qm_in[i].imag;
        }
    }

    npy_double rand = random_uniform(0, 1); // does not exist

    ...

    *measured_out = 1 << argument.act;
}

...

1 个答案:

答案 0 :(得分:0)

事实证明:一个人不能直接使用sed '/eod_clusterName: DEV_WAS_eBBSEOD_CN_DC/{p;s/\S.*/new string to insert/}' file 库来做到这一点。在搜索了numpy标头一段时间后,我发现了这一点。只是不导出随机库。

我的解决方法是将可调用的python传递给ufunc:

numpy.random

构造ufunc时,必须检查传递的对象是否可调用:

static void
ufunc_M( char ** args
       , npy_intp * dimensions
       , npy_intp * steps
       , void * data)
{
    basic_gate_argument_t argument = *((basic_gate_argument_t *) data);
    PYQCS_GATE_GENERIC_SETUP;
    npy_intp i;

    ...

    npy_double randr;
    //==================================================//
    // Get some random value. I do not like the way this
    // is done but it seems like there is no better way.
    PyObject * random_result = PyObject_CallFunctionObjArgs(argument.rng, NULL);

    if(!PyFloat_Check(random_result))
    {
        randr = 0;
    }
    else
    {
        randr = PyFloat_AsDouble(random_result);
    }
    Py_DECREF(random_result);
    //==================================================//

    ...
}

Ufuncs不会失败,因此当传递的函数不返回static int BasicGate_init ( BasicGate * self , PyObject * args) { char type; if(!PyArg_ParseTuple(args, "ClldO" , &type , &(self->argument.act) , &(self->argument.control) , &(self->argument.r) , &(self->argument.rng)) ) { return -1; } if(!PyCallable_Check(self->argument.rng)) { PyErr_SetString(PyExc_TypeError, "random (5th argument) must be a callable (returning float)"); return -1; } ... case 'M': { self->ufunc = PyUFunc_FromFuncAndDataAndSignature( ufunc_M_funcs // func , self->data // data , ufunc_types //types , 1 // ntypes , 2 // nin , 3 // nout , PyUFunc_None // identity , "M_function" // name , "Computes the M (Measurement) gate on a state." // doc , 0 // unused , "(n),(m)->(n),(m),()"); ... } 时,Ufunc将产生废话。