[READ-ONLY] Mirror of https://github.com/shuuji3/python-extension-twister. Experimental Python C extension to generate random numbers by using Mersenne twister
0

Configure Feed

Select the types of activity you want to include in your feed.

python-extension-twister / src / twistermodule.c
3.3 kB 129 lines
1#include <Python.h> 2 3#include <stdio.h> 4#include <time.h> 5 6#include "SFMT-src-1.5.1/SFMT.h" 7 8// 乱数のデータが格納される構造体 9sfmt_t sfmt; 10 11/** 12 * 整数の乱数を num 個 print する関数 13 * @param num print する乱数の数を指定する 14 */ 15void print_rand_int(int num) { 16 // Print header 17 printf("# print %d random int\n", num); 18 fflush(stdout); 19 20 // Print rand 21 for (int i = 0; i < num; i++) { 22 printf("%10llu ", sfmt_genrand_uint64(&sfmt)); 23 if (i % 5 == 4) printf("\n"); 24 } 25 printf("\n"); 26 fflush(stdout); 27} 28 29/** 30 * [0, 1) の乱数を num 個 print する関数 31 * @param num print する乱数の数を指定する 32 */ 33void print_rand(int num) { 34 // Print header 35 printf("# print %d random numbers\n", num); 36 fflush(stdout); 37 38 // Print rands 39 for (int i = 0; i < num; i++) { 40 printf("%10.8f ", sfmt_genrand_real2(&sfmt)); 41 if (i % 5 == 4) printf("\n"); 42 } 43 printf("\n"); 44 fflush(stdout); 45} 46 47/** 48 * print_rand_int() を実行する Python メソッド 49 */ 50static PyObject * 51twister_print_rand_int(PyObject *self, PyObject *args) { 52 int num = 10; 53 if (!PyArg_ParseTuple(args, "|l", &num)) { 54 return NULL; 55 } 56 print_rand_int(num); 57 Py_RETURN_NONE; 58} 59 60/** 61 * print_rand() を実行する Python メソッド 62 */ 63static PyObject * 64twister_print_rand(PyObject *self, PyObject *args) { 65 int num = 10; 66 if (!PyArg_ParseTuple(args, "|l", &num)) { 67 return NULL; 68 } 69 print_rand(num); 70 Py_RETURN_NONE; 71} 72 73/** 74 * 乱数を1つ生成する Python メソッド 75 */ 76static PyObject * 77twister_random(PyObject *self, PyObject *args) { 78 return PyFloat_FromDouble(sfmt_genrand_real2(&sfmt)); 79} 80 81/** 82 * 乱数を1つ生成する Python メソッド 83 */ 84static PyObject * 85twister_randint(PyObject *self, PyObject *args) { 86 // [start, end) のパラメータをパースする 87 long start, end; 88 if (!PyArg_ParseTuple(args, "ll", &start, &end)) { 89 return NULL; 90 } 91 92 // [0, 1) の乱数を、指定した範囲に正規化して、整数に変換する 93 double r = sfmt_genrand_real2(&sfmt); 94 return PyLong_FromLong((long)(r * (end - start) + start)); 95} 96 97/** 98 * 拡張モジュールのメソッドの定義 99 */ 100static PyMethodDef TwisterMethods[] = { 101 {"print_rand_int", twister_print_rand_int, METH_VARARGS, "Print random int num times."}, 102 {"print_rand", twister_print_rand, METH_VARARGS, "Print random x in [0, 1) num times."}, 103 {"random", twister_random, METH_VARARGS, "Generate a random number x in [0, 1)."}, 104 {"randint", twister_randint, METH_VARARGS, "Generate a random int in the range [start, end)."}, 105 {NULL, NULL}, 106}; 107 108/** 109 * 拡張モジュールの定義 110 */ 111static struct PyModuleDef twistermodule = { 112 PyModuleDef_HEAD_INIT, 113 "twister", 114 "Generate random numbers by using Mersenne twister.", 115 -1, 116 TwisterMethods, 117}; 118 119/** 120 * モジュール読み込み時に行われる初期化処理 121 * @return 122 */ 123PyMODINIT_FUNC 124PyInit_twister(void) { 125 // 現在時刻をシードに与えて乱数を初期化する 126 sfmt_init_gen_rand(&sfmt, (uint32_t) time(NULL)); 127 128 return PyModule_Create(&twistermodule); 129}