/* Random objects */

/* ------------------------------------------------------------------
   The code in this module was based on a download from:
	  http://www.math.keio.ac.jp/~matumoto/MT2002/emt19937ar.html

   It was modified in 2002 by Raymond Hettinger as follows:

	* the principal computational lines untouched except for tabbing.

	* renamed genrand_res53() to random_random() and wrapped
	  in python calling/return code.

	* genrand_int32() and the helper functions, init_genrand()
	  and init_by_array(), were declared static, wrapped in
	  Python calling/return code.  also, their global data
	  references were replaced with structure references.

	* unused functions from the original were deleted.
	  new, original C python code was added to implement the
	  Random() interface.

   The following are the verbatim comments from the original code:

   A C-program for MT19937, with initialization improved 2002/1/26.
   Coded by Takuji Nishimura and Makoto Matsumoto.

   Before using, initialize the state by using init_genrand(seed)
   or init_by_array(init_key, key_length).

   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

     1. Redistributions of source code must retain the above copyright
	notice, this list of conditions and the following disclaimer.

     2. Redistributions in binary form must reproduce the above copyright
	notice, this list of conditions and the following disclaimer in the
	documentation and/or other materials provided with the distribution.

     3. The names of its contributors may not be used to endorse or promote
	products derived from this software without specific prior written
	permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


   Any feedback is very welcome.
   http://www.math.keio.ac.jp/matumoto/emt.html
   email: matumoto@math.keio.ac.jp
*/

/* ---------------------------------------------------------------*/

#include "Python.h"
#include <time.h>		// for seeding to current time

/* Period parameters -- These are all magic.  Don't change. */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL	/* constant vector a */
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */

typedef struct {
	PyObject_HEAD
	unsigned long state[N];
	int index;
} RandomObject;

static PyTypeObject Random_Type;

#define RandomObject_Check(v)	   ((v)->ob_type == &Random_Type)


/* Random methods */


/* generates a random number on [0,0xffffffff]-interval */
static unsigned long
genrand_int32(RandomObject *self)
{
	unsigned long y;
	static unsigned long mag01[2]={0x0UL, MATRIX_A};
	/* mag01[x] = x * MATRIX_A  for x=0,1 */
	unsigned long *mt;

	mt = self->state;
	if (self->index >= N) { /* generate N words at one time */
		int kk;

		for (kk=0;kk<N-M;kk++) {
			y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
			mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
		}
		for (;kk<N-1;kk++) {
			y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
			mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
	}
		y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
		mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];

		self->index = 0;
	}

    y = mt[self->index++];
    y ^= (y >> 11);
    y ^= (y << 7) & 0x9d2c5680UL;
    y ^= (y << 15) & 0xefc60000UL;
    y ^= (y >> 18);
    return y;
}

/* random_random is the function named genrand_res53 in the original code;
 * generates a random number on [0,1) with 53-bit resolution; note that
 * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as
 * multiply-by-reciprocal in the (likely vain) hope that the compiler will
 * optimize the division away at compile-time.  67108864 is 2**26.  In
 * effect, a contains 27 random bits shifted left 26, and b fills in the
 * lower 26 bits of the 53-bit numerator.
 * The orginal code credited Isaku Wada for this algorithm, 2002/01/09.
 */
static PyObject *
random_random(RandomObject *self)
{
	unsigned long a=genrand_int32(self)>>5, b=genrand_int32(self)>>6;
    	return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
}

/* initializes mt[N] with a seed */
static void
init_genrand(RandomObject *self, unsigned long s)
{
	int mti;
	unsigned long *mt;

	mt = self->state;
	mt[0]= s & 0xffffffffUL;
	for (mti=1; mti<N; mti++) {
		mt[mti] =
		(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
		/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
		/* In the previous versions, MSBs of the seed affect   */
		/* only MSBs of the array mt[]. 		       */
		/* 2002/01/09 modified by Makoto Matsumoto	       */
		mt[mti] &= 0xffffffffUL;
		/* for >32 bit machines */
	}
	self->index = mti;
	return;
}

/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
static PyObject *
init_by_array(RandomObject *self, unsigned long init_key[], unsigned long key_length)
{
	unsigned int i, j, k;	/* was signed in the original code. RDH 12/16/2002 */
	unsigned long *mt;

	mt = self->state;
	init_genrand(self, 19650218UL);
	i=1; j=0;
	k = (N>key_length ? N : key_length);
	for (; k; k--) {
		mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
			 + init_key[j] + j; /* non linear */
		mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
		i++; j++;
		if (i>=N) { mt[0] = mt[N-1]; i=1; }
		if (j>=key_length) j=0;
	}
	for (k=N-1; k; k--) {
		mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
			 - i; /* non linear */
		mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
		i++;
		if (i>=N) { mt[0] = mt[N-1]; i=1; }
	}

    mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
    Py_INCREF(Py_None);
    return Py_None;
}

/*
 * The rest is Python-specific code, neither part of, nor derived from, the
 * Twister download.
 */

static PyObject *
random_seed(RandomObject *self, PyObject *args)
{
	PyObject *result = NULL;	/* guilty until proved innocent */
	PyObject *masklower = NULL;
	PyObject *thirtytwo = NULL;
	PyObject *n = NULL;
	unsigned long *key = NULL;
	unsigned long keymax;		/* # of allocated slots in key */
	unsigned long keyused;		/* # of used slots in key */

	PyObject *arg = NULL;

	if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg))
		return NULL;

	if (arg == NULL || arg == Py_None) {
		time_t now;

		time(&now);
		init_genrand(self, (unsigned long)now);
		Py_INCREF(Py_None);
		return Py_None;
	}
	/* If the arg is an int or long, use its absolute value; else use
	 * the absolute value of its hash code.
	 */
	if (PyInt_Check(arg) || PyLong_Check(arg))
		n = PyNumber_Absolute(arg);
	else {
		long hash = PyObject_Hash(arg);
		if (hash == -1)
			goto Done;
		n = PyLong_FromUnsignedLong((unsigned long)hash);
	}
	if (n == NULL)
		goto Done;

	/* Now split n into 32-bit chunks, from the right.  Each piece is
	 * stored into key, which has a capacity of keymax chunks, of which
	 * keyused are filled.  Alas, the repeated shifting makes this a
	 * quadratic-time algorithm; we'd really like to use
	 * _PyLong_AsByteArray here, but then we'd have to break into the
	 * long representation to figure out how big an array was needed
	 * in advance.
	 */
	keymax = 8; 	/* arbitrary; grows later if needed */
	keyused = 0;
	key = (unsigned long *)PyMem_Malloc(keymax * sizeof(*key));
	if (key == NULL)
		goto Done;

	masklower = PyLong_FromUnsignedLong(0xffffffffU);
	if (masklower == NULL)
		goto Done;
	thirtytwo = PyInt_FromLong(32L);
	if (thirtytwo == NULL)
		goto Done;
	while (PyObject_IsTrue(n)) {
		PyObject *newn;
		PyObject *pychunk;
		unsigned long chunk;

		pychunk = PyNumber_And(n, masklower);
		if (pychunk == NULL)
			goto Done;
		chunk = PyLong_AsUnsignedLong(pychunk);
		Py_DECREF(pychunk);
		if (chunk == (unsigned long)-1 && PyErr_Occurred())
			goto Done;
		newn = PyNumber_Rshift(n, thirtytwo);
		if (newn == NULL)
			goto Done;
		Py_DECREF(n);
		n = newn;
		if (keyused >= keymax) {
			unsigned long bigger = keymax << 1;
			if ((bigger >> 1) != keymax) {
				PyErr_NoMemory();
				goto Done;
			}
			key = (unsigned long *)PyMem_Realloc(key,
						bigger * sizeof(*key));
			if (key == NULL)
				goto Done;
			keymax = bigger;
		}
		assert(keyused < keymax);
		key[keyused++] = chunk;
	}

	if (keyused == 0)
		key[keyused++] = 0UL;
	result = init_by_array(self, key, keyused);
Done:
	Py_XDECREF(masklower);
	Py_XDECREF(thirtytwo);
	Py_XDECREF(n);
	PyMem_Free(key);
	return result;
}

static PyObject *
random_getstate(RandomObject *self)
{
	PyObject *state;
	PyObject *element;
	int i;

	state = PyTuple_New(N+1);
	if (state == NULL)
		return NULL;
	for (i=0; i<N ; i++) {
		element = PyInt_FromLong((long)(self->state[i]));
		if (element == NULL)
			goto Fail;
		PyTuple_SET_ITEM(state, i, element);
	}
	element = PyInt_FromLong((long)(self->index));
	if (element == NULL)
		goto Fail;
	PyTuple_SET_ITEM(state, i, element);
	return state;

Fail:
	Py_DECREF(state);
	return NULL;
}

static PyObject *
random_setstate(RandomObject *self, PyObject *state)
{
	int i;
	long element;

	if (!PyTuple_Check(state)) {
		PyErr_SetString(PyExc_TypeError,
			"state vector must be a tuple");
		return NULL;
	}
	if (PyTuple_Size(state) != N+1) {
		PyErr_SetString(PyExc_ValueError,
			"state vector is the wrong size");
		return NULL;
	}

	for (i=0; i<N ; i++) {
		element = PyInt_AsLong(PyTuple_GET_ITEM(state, i));
		if (element == -1 && PyErr_Occurred())
			return NULL;
		self->state[i] = (unsigned long)element;
	}

	element = PyInt_AsLong(PyTuple_GET_ITEM(state, i));
	if (element == -1 && PyErr_Occurred())
		return NULL;
	self->index = (int)element;

	Py_INCREF(Py_None);
	return Py_None;
}

/*
Jumpahead should be a fast way advance the generator n-steps ahead, but
lacking a formula for that, the next best is to use n and the existing
state to create a new state far away from the original.

The generator uses constant spaced additive feedback, so shuffling the
state elements ought to produce a state which would not be encountered
(in the near term) by calls to random().  Shuffling is normally
implemented by swapping the ith element with another element ranging
from 0 to i inclusive.  That allows the element to have the possibility
of not being moved.  Since the goal is to produce a new, different
state, the swap element is ranged from 0 to i-1 inclusive.  This assures
that each element gets moved at least once.

To make sure that consecutive calls to jumpahead(n) produce different
states (even in the rare case of involutory shuffles), i+1 is added to
each element at position i.  Successive calls are then guaranteed to
have changing (growing) values as well as shuffled positions.

Finally, the self->index value is set to N so that the generator itself
kicks in on the next call to random().	This assures that all results
have been through the generator and do not just reflect alterations to
the underlying state.
*/

static PyObject *
random_jumpahead(RandomObject *self, PyObject *n)
{
	long i, j;
	PyObject *iobj;
	PyObject *remobj;
	unsigned long *mt, tmp;

	if (!PyInt_Check(n) && !PyLong_Check(n)) {
		PyErr_Format(PyExc_TypeError, "jumpahead requires an "
			     "integer, not '%s'",
			     n->ob_type->tp_name);
		return NULL;
	}

	mt = self->state;
	for (i = N-1; i > 1; i--) {
		iobj = PyInt_FromLong(i);
		if (iobj == NULL)
			return NULL;
		remobj = PyNumber_Remainder(n, iobj);
		Py_DECREF(iobj);
		if (remobj == NULL)
			return NULL;
		j = PyInt_AsLong(remobj);
		Py_DECREF(remobj);
		if (j == -1L && PyErr_Occurred())
			return NULL;
		tmp = mt[i];
		mt[i] = mt[j];
		mt[j] = tmp;
	}

	for (i = 0; i < N; i++)
		mt[i] += i+1;

	self->index = N;
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	RandomObject *self;
	PyObject *tmp;

	self = (RandomObject *)type->tp_alloc(type, 0);
	if (self == NULL)
		return NULL;
	tmp = random_seed(self, args);
	if (tmp == NULL) {
		Py_DECREF(self);
		return NULL;
	}
	Py_DECREF(tmp);
	return (PyObject *)self;
}

static PyMethodDef random_methods[] = {
	{"random",	(PyCFunction)random_random,  METH_NOARGS,
		PyDoc_STR("random() -> x in the interval [0, 1).")},
	{"seed",	(PyCFunction)random_seed,  METH_VARARGS,
		PyDoc_STR("seed([n]) -> None.  Defaults to current time.")},
	{"getstate",	(PyCFunction)random_getstate,  METH_NOARGS,
		PyDoc_STR("getstate() -> tuple containing the current state.")},
	{"setstate",	  (PyCFunction)random_setstate,  METH_O,
		PyDoc_STR("setstate(state) -> None.  Restores generator state.")},
	{"jumpahead",	(PyCFunction)random_jumpahead,	METH_O,
		PyDoc_STR("jumpahead(int) -> None.  Create new state from "
			  "existing state and integer.")},
	{NULL,		NULL}		/* sentinel */
};

PyDoc_STRVAR(random_doc,
"Random() -> create a random number generator with its own internal state.");

static PyTypeObject Random_Type = {
	PyObject_HEAD_INIT(NULL)
	0,				/*ob_size*/
	"_random.Random",		/*tp_name*/
	sizeof(RandomObject),		/*tp_basicsize*/
	0,				/*tp_itemsize*/
	/* methods */
	0,				/*tp_dealloc*/
	0,				/*tp_print*/
	0,				/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
	0,				/*tp_as_number*/
	0,				/*tp_as_sequence*/
	0,				/*tp_as_mapping*/
	0,				/*tp_hash*/
	0,				/*tp_call*/
	0,				/*tp_str*/
	PyObject_GenericGetAttr,	/*tp_getattro*/
	0,				/*tp_setattro*/
	0,				/*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/*tp_flags*/
	random_doc,			/*tp_doc*/
	0,				/*tp_traverse*/
	0,				/*tp_clear*/
	0,				/*tp_richcompare*/
	0,				/*tp_weaklistoffset*/
	0,				/*tp_iter*/
	0,				/*tp_iternext*/
	random_methods, 		/*tp_methods*/
	0,				/*tp_members*/
	0,				/*tp_getset*/
	0,				/*tp_base*/
	0,				/*tp_dict*/
	0,				/*tp_descr_get*/
	0,				/*tp_descr_set*/
	0,				/*tp_dictoffset*/
	0,				/*tp_init*/
	PyType_GenericAlloc,		/*tp_alloc*/
	random_new,			/*tp_new*/
	_PyObject_Del,			/*tp_free*/
	0,				/*tp_is_gc*/
};

PyDoc_STRVAR(module_doc,
"Module implements the Mersenne Twister random number generator.");

PyMODINIT_FUNC
init_random(void)
{
	PyObject *m;

	if (PyType_Ready(&Random_Type) < 0)
		return;
	m = Py_InitModule3("_random", NULL, module_doc);
	Py_INCREF(&Random_Type);
	PyModule_AddObject(m, "Random", (PyObject *)&Random_Type);
}
