/* File: random_xsb.c ** Author(s): Baoqiu Cui ** Contact: xsb-contact@cs.sunysb.edu ** ** Copyright (C) The Research Foundation of SUNY, 1999 ** ** XSB is free software; you can redistribute it and/or modify it under the ** terms of the GNU Library General Public License as published by the Free ** Software Foundation; either version 2 of the License, or (at your option) ** any later version. ** ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ** FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for ** more details. ** ** You should have received a copy of the GNU Library General Public License ** along with XSB; if not, write to the Free Software Foundation, ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: random_xsb.c,v 1.6 2002/01/23 17:08:10 dwarren Exp $ ** */ /* * This is the implementation of Wichmann-Hill Random Number Generator: * * B. A. Wichmann and I. D. Hill. Algorithm AS 183: An efficient and * portable pseudo-random number generator. Applied Statistics 31 * (1982), 188--190. * * See also: * * Correction to Algorithm AS 183. Applied Statistics 33 (1984) 123, * * A. I. McLeod. A remark on Algorithm AS 183. Applied Statistics 34 * (1985), 198--200. */ #include "xsb_config.h" #include "cell_xsb.h" #include "cinterf.h" #include "deref.h" #include "register.h" #include "ptoc_tag_xsb_i.h" static short IX = 6293; static short IY = 21877; static short IZ = 7943; static double TX = 1.0/30269.0; static double TY = 1.0/30307.0; static double TZ = 1.0/30323.0; /* * Returns a float number within the range [0.0, 1.0) in reg 2. * ret_random() returns FALSE if there is an error, TRUE if everything is OK. */ int ret_random() { short X, Y, Z; double T; Cell term; X = (IX*171) % 30269; Y = (IY*172) % 30307; Z = (IZ*170) % 30323; T = X*TX + Y*TY + Z*TZ; IX = X; IY = Y; IZ = Z; term = ptoc_tag(2); if (isref(term)) { ctop_float(2, T - (int)T); return TRUE; } else return FALSE; } /* * Unifies reg 2,3,4 with the random seeds IX, IY, IZ. * getrand() returns FALSE if there is an error, TRUE if everything is OK. */ int getrand() { Cell term; term = ptoc_tag(2); if (isref(term)) ctop_int(2, IX); else if (!isinteger(term) || (oint_val(term) != IX)) return FALSE; term = ptoc_tag(3); if (isref(term)) ctop_int(3, IY); else if (!isinteger(term) || (oint_val(term) != IY)) return FALSE; term = ptoc_tag(4); if (isref(term)) ctop_int(4, IZ); else if (!isinteger(term) || (oint_val(term) != IZ)) return FALSE; return TRUE; } /* * Sets the random seeds IX, IY and IZ using reg 2,3,4. The type and * range checking are done in random.P. */ void setrand() { IX = ptoc_int(2); IY = ptoc_int(3); IZ = ptoc_int(4); }