random_xsb.c

00001 /* File:      random_xsb.c
00002 ** Author(s): Baoqiu Cui
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1999
00006 ** 
00007 ** XSB is free software; you can redistribute it and/or modify it under the
00008 ** terms of the GNU Library General Public License as published by the Free
00009 ** Software Foundation; either version 2 of the License, or (at your option)
00010 ** any later version.
00011 ** 
00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00015 ** more details.
00016 ** 
00017 ** You should have received a copy of the GNU Library General Public License
00018 ** along with XSB; if not, write to the Free Software Foundation,
00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 **
00021 ** $Id: random_xsb.c,v 1.11 2006/01/05 22:49:52 dwarren Exp $
00022 ** 
00023 */
00024 
00025 /*
00026  * This is the implementation of Wichmann-Hill Random Number Generator:
00027  *
00028  *     B. A. Wichmann and I. D. Hill.  Algorithm AS 183: An efficient and
00029  *     portable pseudo-random number generator.  Applied Statistics 31
00030  *     (1982), 188--190.
00031  *
00032  * See also:
00033  *
00034  *     Correction to Algorithm AS 183.  Applied Statistics 33 (1984) 123,
00035  *
00036  *     A. I. McLeod.  A remark on Algorithm AS 183.  Applied Statistics 34
00037  *     (1985), 198--200.
00038  */
00039 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 
00043 #include "xsb_config.h"
00044 #include "cell_xsb.h"
00045 #include "cinterf.h"
00046 #include "deref.h"
00047 #include "register.h"
00048 #include "ptoc_tag_xsb_i.h"
00049 #include "error_xsb.h"
00050 #include "context.h"
00051 #include "memory_xsb.h"
00052 
00053 #ifndef MULTI_THREAD
00054 struct random_seeds_t *random_seeds = 0;
00055 #endif
00056 
00057 struct random_seeds_t *init_random_seeds() {
00058 
00059   struct random_seeds_t *seeds;
00060   seeds = (struct random_seeds_t *)mem_alloc(sizeof(struct random_seeds_t),OTHER_SPACE);
00061   if (!seeds) xsb_abort("No space for random seeds!!");
00062   seeds->IX = 6293;
00063   seeds->IY = 21877;
00064   seeds->IZ = 7943;
00065   seeds->TX = 1.0/30269.0;
00066   seeds->TY = 1.0/30307.0;
00067   seeds->TZ = 1.0/30323.0;
00068   return seeds;
00069 }
00070 
00071 /*
00072  * Returns a float number within the range [0.0, 1.0) in reg 2.
00073  * ret_random() returns FALSE if there is an error, TRUE if everything is OK.
00074  */
00075 int ret_random(CTXTdecl) {
00076   short X, Y, Z;
00077   double T;
00078   Cell term;
00079 
00080   if (!random_seeds) random_seeds = init_random_seeds();
00081 
00082   X = (random_seeds->IX*171) % 30269;
00083   Y = (random_seeds->IY*172) % 30307;
00084   Z = (random_seeds->IZ*170) % 30323;
00085   T = X*random_seeds->TX + Y*random_seeds->TY + Z*random_seeds->TZ;
00086   random_seeds->IX = X;
00087   random_seeds->IY = Y;
00088   random_seeds->IZ = Z;
00089 
00090   term = ptoc_tag(CTXTc 2);
00091   if (isref(term)) {
00092     ctop_float(CTXTc 2, T - (int)T);
00093     return TRUE;
00094   }
00095   else return FALSE;
00096 }    
00097 
00098 /*
00099  * Unifies reg 2,3,4 with the random seeds IX, IY, IZ.  
00100  * getrand() returns FALSE if there is an error, TRUE if everything is OK.
00101  */
00102 int getrand(CTXTdecl) {
00103   Cell term;
00104 
00105   if (!random_seeds) random_seeds = init_random_seeds();
00106   term = ptoc_tag(CTXTc 2);
00107   if (isref(term))
00108     ctop_int(CTXTc 2, random_seeds->IX);
00109   else if (!isinteger(term) || (oint_val(term) != random_seeds->IX))
00110     return FALSE;
00111 
00112   term = ptoc_tag(CTXTc 3);
00113   if (isref(term))
00114     ctop_int(CTXTc 3, random_seeds->IY);
00115   else if (!isinteger(term) || (oint_val(term) != random_seeds->IY))
00116     return FALSE;
00117 
00118   term = ptoc_tag(CTXTc 4);
00119   if (isref(term))
00120     ctop_int(CTXTc 4, random_seeds->IZ);
00121   else if (!isinteger(term) || (oint_val(term) != random_seeds->IZ))
00122     return FALSE;
00123 
00124   return TRUE;
00125 }
00126 
00127 /*
00128  * Sets the random seeds IX, IY and IZ using reg 2,3,4.  The type and
00129  * range checking are done in random.P.
00130  */
00131 void setrand(CTXTdecl) {
00132   if (!random_seeds) random_seeds = init_random_seeds();
00133   random_seeds->IX = ptoc_int(CTXTc 2);
00134   random_seeds->IY = ptoc_int(CTXTc 3);
00135   random_seeds->IZ = ptoc_int(CTXTc 4);
00136 }

Generated on Wed Jul 26 13:30:42 2006 for XSB by  doxygen 1.4.5