File: clcg2.c

package info (click to toggle)
scilab 4.0-12
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 100,640 kB
  • ctags: 57,333
  • sloc: ansic: 377,889; fortran: 242,862; xml: 179,819; tcl: 42,062; sh: 10,593; ml: 9,441; makefile: 4,377; cpp: 1,354; java: 621; csh: 260; yacc: 247; perl: 130; lex: 126; asm: 72; lisp: 30
file content (93 lines) | stat: -rw-r--r-- 2,427 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*  
 *  PURPOSE
 *     uniform random number generator developed by Pierre 
 *     Lecuyer based on a clever and tested combination of 
 *     two linear congruential sequences
 *
 *        s1 <- a1*s1 mod m1 ,  a1 = 40014, m1 = 2147483563
 *        s2 <- a2*s2 mod m2 ,  a2 = 40692, m2 = 2147483399
 *
 *        output <-  s1-s2 mod (m1 - 1)  
 *
 *        so output is in [0, 2147483561], period about 2.3 10^18
 *
 *        The state is given by (s1, s2). In case of a user
 *        modification of the state we must have :
 * 
 *              s1 in [1, m1-1]
 *              s2 in [1, m2-1]
 *
 *  ORIGIN
 *     The basic code is provided at the Luc Devroye 's home page.
 *     Modifications by Bruno Pincon (in particular added routines 
 *     to set and get the state, and modify the generator to get 
 *     exactly  s1-s2 mod (m1 - 1) for "coherence" with the others 
 *     generators : provides numbers in [0, MaxRngInt(generator)] 
 *     (see NOTE some lines after)
 *
 */

#include "../graphics/Math.h" /* to use sciprint */
#include <math.h>


/* initial default state (seeds) : */
static long s1 = 1234567890 ;
static long s2 = 123456789  ;


unsigned long clcg2()
{
  register long k,z;

  /*  s1 = a1*s1 mod m1  (Schrage 's method)  */
  k= s1 /53668;
  s1 =40014*(s1%53668)-k*12211;
  if (s1 < 0) s1 += 2147483563;

  /*  s2 = a2*s2 mod m2  (Schrage 's method)  */
  k=s2/52774;
  s2=40692*(s2%52774)-k*3791;
  if (s2 < 0) s2 += 2147483399;

  /* final step : z = s1-s2 mod m1-1  */
  z = s1 - s2;  /* here z is in [2-m2,m1-2] */
  if (z < 0) z += 2147483562;

  /* NOTE : in the  original implementation the final test is :
   *     if (z < 1) z += 2147483562;
   * 
   *   which is not exactly  z = s1-s2 mod (m1 - 1)
   *
   *   This is also why it is different from the version used by
   *   randlib.
   */
  
  return( (unsigned long) z );
}

int set_state_clcg2(double g1, double g2)
{
  
  if ( g1 == floor(g1) && g2 == floor(g2)  && 
       1 <= g1 && g1 <= 2147483562    &&
       1 <= g2 && g2 <= 2147483398 )
    {
      s1 = (long) g1;
      s2 = (long) g2;
      return ( 1 );
    }
  else
    {
      sciprint("\n\r bad seeds for clcg2, must be integers with  s1 in [1, 2147483562]");
      sciprint("\n\r                                        and  s2 in [1, 2147483398]\n\r");
      return ( 0 );
    }
}

void get_state_clcg2(double g[])
{
  g[0] = (double) s1;
  g[1] = (double) s2;
}