FairRoot/PandaRoot
ranlxd.cxx
Go to the documentation of this file.
1 
2 /*******************************************************************************
3 *
4 * File ranlxd.c
5 *
6 * Copyright (C) 2005 Martin Luescher
7 *
8 * This software is distributed under the terms of the GNU General Public
9 * License (GPL)
10 *
11 * Random number generator "ranlxd". See the notes
12 *
13 * "User's guide for ranlxs and ranlxd v3.2" (December 2005)
14 *
15 * "Algorithms used in ranlux v3.0" (May 2001)
16 *
17 * for a detailed description
18 *
19 * The externally accessible functions are
20 *
21 * void ranlxd(double r[],int n)
22 * Computes the next n double-precision random numbers and
23 * assigns them to the elements r[0],...,r[n-1] of the array r[]
24 *
25 * void rlxd_init(int level,int seed)
26 * Initialization of the generator
27 *
28 * int rlxd_size(void)
29 * Returns the number of integers required to save the state of
30 * the generator
31 *
32 * void rlxd_get(int state[])
33 * Extracts the current state of the generator and stores the
34 * information in the array state[N] where N>=rlxd_size()
35 *
36 * void rlxd_reset(int state[])
37 * Resets the generator to the state defined by the array state[N]
38 *
39 *******************************************************************************/
40 
41 #define RANLXD_C
42 
43 #include <limits.h>
44 #include <float.h>
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <math.h>
48 
49 #if (defined SSE)
50 
51 typedef struct
52 {
53  float c1,c2,c3,c4;
54 } vec_t __attribute__ ((aligned (16)));
55 
56 typedef struct
57 {
58  vec_t c1,c2;
59 } dble_vec_t __attribute__ ((aligned (16)));
60 
61 static int init=0,pr,prm,ir,jr,is,is_old,next[96];
62 static vec_t one,one_bit,carry;
63 
64 static union
65 {
66  dble_vec_t vec[12];
67  float num[96];
68 } x __attribute__ ((aligned (16)));
69 
70 #define STEP(pi,pj) \
71  __asm__ __volatile__ ("movaps %4, %%xmm4 \n\t" \
72  "movaps %%xmm2, %%xmm3 \n\t" \
73  "subps %2, %%xmm4 \n\t" \
74  "movaps %%xmm1, %%xmm5 \n\t" \
75  "cmpps $0x6, %%xmm4, %%xmm2 \n\t" \
76  "andps %%xmm2, %%xmm5 \n\t" \
77  "subps %%xmm3, %%xmm4 \n\t" \
78  "andps %%xmm0, %%xmm2 \n\t" \
79  "addps %%xmm4, %%xmm5 \n\t" \
80  "movaps %%xmm5, %0 \n\t" \
81  "movaps %5, %%xmm6 \n\t" \
82  "movaps %%xmm2, %%xmm3 \n\t" \
83  "subps %3, %%xmm6 \n\t" \
84  "movaps %%xmm1, %%xmm7 \n\t" \
85  "cmpps $0x6, %%xmm6, %%xmm2 \n\t" \
86  "andps %%xmm2, %%xmm7 \n\t" \
87  "subps %%xmm3, %%xmm6 \n\t" \
88  "andps %%xmm0, %%xmm2 \n\t" \
89  "addps %%xmm6, %%xmm7 \n\t" \
90  "movaps %%xmm7, %1" \
91  : \
92  "=m" ((*pi).c1), \
93  "=m" ((*pi).c2) \
94  : \
95  "m" ((*pi).c1), \
96  "m" ((*pi).c2), \
97  "m" ((*pj).c1), \
98  "m" ((*pj).c2) \
99  : \
100  "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7")
101 
102 
103 static void error(int no)
104 {
105  switch(no)
106  {
107  case 1:
108  printf("Error in subroutine rlxd_init\n");
109  printf("Bad choice of luxury level (should be 1 or 2)\n");
110  break;
111  case 2:
112  printf("Error in subroutine rlxd_init\n");
113  printf("Bad choice of seed (should be between 1 and 2^31-1)\n");
114  break;
115  case 3:
116  printf("Error in rlxd_get\n");
117  printf("Undefined state (ranlxd is not initialized\n");
118  break;
119  case 5:
120  printf("Error in rlxd_reset\n");
121  printf("Unexpected input data\n");
122  break;
123  }
124  printf("Program aborted\n");
125  exit(0);
126 }
127 
128 
129 static void update(void)
130 {
131  int k,kmax;
132  dble_vec_t *pmin,*pmax,*pi,*pj;
133 
134  kmax=pr;
135  pmin=&x.vec[0];
136  pmax=pmin+12;
137  pi=&x.vec[ir];
138  pj=&x.vec[jr];
139 
140  __asm__ __volatile__ ("movaps %0, %%xmm0 \n\t"
141  "movaps %1, %%xmm1 \n\t"
142  "movaps %2, %%xmm2"
143  :
144  :
145  "m" (one_bit),
146  "m" (one),
147  "m" (carry)
148  :
149  "xmm0", "xmm1", "xmm2");
150 
151  for (k=0;k<kmax;k++)
152  {
153  STEP(pi,pj);
154  pi+=1;
155  pj+=1;
156  if (pi==pmax)
157  pi=pmin;
158  if (pj==pmax)
159  pj=pmin;
160  }
161 
162  __asm__ __volatile__ ("movaps %%xmm2, %0"
163  :
164  "=m" (carry));
165 
166  ir+=prm;
167  jr+=prm;
168  if (ir>=12)
169  ir-=12;
170  if (jr>=12)
171  jr-=12;
172  is=8*ir;
173  is_old=is;
174 }
175 
176 
177 static void define_constants(void)
178 {
179  int k;
180  float b;
181 
182  one.c1=1.0f;
183  one.c2=1.0f;
184  one.c3=1.0f;
185  one.c4=1.0f;
186 
187  b=(float)(ldexp(1.0,-24));
188  one_bit.c1=b;
189  one_bit.c2=b;
190  one_bit.c3=b;
191  one_bit.c4=b;
192 
193  for (k=0;k<96;k++)
194  {
195  next[k]=(k+1)%96;
196  if ((k%4)==3)
197  next[k]=(k+5)%96;
198  }
199 }
200 
201 
202 void rlxd_init(int level,int seed)
203 {
204  int i,k,l;
205  int ibit,jbit,xbit[31];
206  int ix,iy;
207 
209 
210  if (level==1)
211  pr=202;
212  else if (level==2)
213  pr=397;
214  else
215  error(1);
216 
217  i=seed;
218 
219  for (k=0;k<31;k++)
220  {
221  xbit[k]=i%2;
222  i/=2;
223  }
224 
225  if ((seed<=0)||(i!=0))
226  error(2);
227 
228  ibit=0;
229  jbit=18;
230 
231  for (i=0;i<4;i++)
232  {
233  for (k=0;k<24;k++)
234  {
235  ix=0;
236 
237  for (l=0;l<24;l++)
238  {
239  iy=xbit[ibit];
240  ix=2*ix+iy;
241 
242  xbit[ibit]=(xbit[ibit]+xbit[jbit])%2;
243  ibit=(ibit+1)%31;
244  jbit=(jbit+1)%31;
245  }
246 
247  if ((k%4)!=i)
248  ix=16777215-ix;
249 
250  x.num[4*k+i]=(float)(ldexp((double)(ix),-24));
251  }
252  }
253 
254  carry.c1=0.0f;
255  carry.c2=0.0f;
256  carry.c3=0.0f;
257  carry.c4=0.0f;
258 
259  ir=0;
260  jr=7;
261  is=91;
262  is_old=0;
263  prm=pr%12;
264  init=1;
265 }
266 
267 
268 void ranlxd(double r[],int n)
269 {
270  int k;
271 
272  if (init==0)
273  rlxd_init(1,1);
274 
275  for (k=0;k<n;k++)
276  {
277  is=next[is];
278  if (is==is_old)
279  update();
280  r[k]=(double)(x.num[is+4])+(double)(one_bit.c1*x.num[is]);
281  }
282 }
283 
284 
285 int rlxd_size(void)
286 {
287  return(105);
288 }
289 
290 
291 void rlxd_get(int state[])
292 {
293  int k;
294  float base;
295 
296  if (init==0)
297  error(3);
298 
299  base=(float)(ldexp(1.0,24));
300  state[0]=rlxd_size();
301 
302  for (k=0;k<96;k++)
303  state[k+1]=(int)(base*x.num[k]);
304 
305  state[97]=(int)(base*carry.c1);
306  state[98]=(int)(base*carry.c2);
307  state[99]=(int)(base*carry.c3);
308  state[100]=(int)(base*carry.c4);
309 
310  state[101]=pr;
311  state[102]=ir;
312  state[103]=jr;
313  state[104]=is;
314 }
315 
316 
317 void rlxd_reset(int state[])
318 {
319  int k;
320 
322 
323  if (state[0]!=rlxd_size())
324  error(5);
325 
326  for (k=0;k<96;k++)
327  {
328  if ((state[k+1]<0)||(state[k+1]>=167777216))
329  error(5);
330 
331  x.num[k]=(float)(ldexp((double)(state[k+1]),-24));
332  }
333 
334  if (((state[97]!=0)&&(state[97]!=1))||
335  ((state[98]!=0)&&(state[98]!=1))||
336  ((state[99]!=0)&&(state[99]!=1))||
337  ((state[100]!=0)&&(state[100]!=1)))
338  error(5);
339 
340  carry.c1=(float)(ldexp((double)(state[97]),-24));
341  carry.c2=(float)(ldexp((double)(state[98]),-24));
342  carry.c3=(float)(ldexp((double)(state[99]),-24));
343  carry.c4=(float)(ldexp((double)(state[100]),-24));
344 
345  pr=state[101];
346  ir=state[102];
347  jr=state[103];
348  is=state[104];
349  is_old=8*ir;
350  prm=pr%12;
351  init=1;
352 
353  if (((pr!=202)&&(pr!=397))||
354  (ir<0)||(ir>11)||(jr<0)||(jr>11)||(jr!=((ir+7)%12))||
355  (is<0)||(is>91))
356  error(5);
357 }
358 
359 #else
360 
361 #define BASE 0x1000000
362 #define MASK 0xffffff
363 
364 typedef struct
365 {
366  int c1,c2,c3,c4;
367 } vec_t;
368 
369 typedef struct
370 {
372 } dble_vec_t;
373 
374 static int init=0,pr,prm,ir,jr,is,is_old,next[96];
375 static double one_bit;
376 static vec_t carry;
377 
378 static union
379 {
381  int num[96];
382 } x;
383 
384 #define STEP(pi,pj) \
385  d=(*pj).c1.c1-(*pi).c1.c1-carry.c1; \
386  (*pi).c2.c1+=(d<0); \
387  d+=BASE; \
388  (*pi).c1.c1=d&MASK; \
389  d=(*pj).c1.c2-(*pi).c1.c2-carry.c2; \
390  (*pi).c2.c2+=(d<0); \
391  d+=BASE; \
392  (*pi).c1.c2=d&MASK; \
393  d=(*pj).c1.c3-(*pi).c1.c3-carry.c3; \
394  (*pi).c2.c3+=(d<0); \
395  d+=BASE; \
396  (*pi).c1.c3=d&MASK; \
397  d=(*pj).c1.c4-(*pi).c1.c4-carry.c4; \
398  (*pi).c2.c4+=(d<0); \
399  d+=BASE; \
400  (*pi).c1.c4=d&MASK; \
401  d=(*pj).c2.c1-(*pi).c2.c1; \
402  carry.c1=(d<0); \
403  d+=BASE; \
404  (*pi).c2.c1=d&MASK; \
405  d=(*pj).c2.c2-(*pi).c2.c2; \
406  carry.c2=(d<0); \
407  d+=BASE; \
408  (*pi).c2.c2=d&MASK; \
409  d=(*pj).c2.c3-(*pi).c2.c3; \
410  carry.c3=(d<0); \
411  d+=BASE; \
412  (*pi).c2.c3=d&MASK; \
413  d=(*pj).c2.c4-(*pi).c2.c4; \
414  carry.c4=(d<0); \
415  d+=BASE; \
416  (*pi).c2.c4=d&MASK
417 
418 
419 static void error(int no)
420 {
421  switch(no)
422  {
423  case 0:
424  printf("Error in rlxd_init\n");
425  printf("Arithmetic on this machine is not suitable for ranlxd\n");
426  break;
427  case 1:
428  printf("Error in subroutine rlxd_init\n");
429  printf("Bad choice of luxury level (should be 1 or 2)\n");
430  break;
431  case 2:
432  printf("Error in subroutine rlxd_init\n");
433  printf("Bad choice of seed (should be between 1 and 2^31-1)\n");
434  break;
435  case 3:
436  printf("Error in rlxd_get\n");
437  printf("Undefined state (ranlxd is not initialized)\n");
438  break;
439  case 4:
440  printf("Error in rlxd_reset\n");
441  printf("Arithmetic on this machine is not suitable for ranlxd\n");
442  break;
443  case 5:
444  printf("Error in rlxd_reset\n");
445  printf("Unexpected input data\n");
446  break;
447  }
448  printf("Program aborted\n");
449  exit(0);
450 }
451 
452 
453 static void update(void)
454 {
455  int k,kmax,d;
456  dble_vec_t *pmin,*pmax,*pi,*pj;
457 
458  kmax=pr;
459  pmin=&x.vec[0];
460  pmax=pmin+12;
461  pi=&x.vec[ir];
462  pj=&x.vec[jr];
463 
464  for (k=0;k<kmax;k++)
465  {
466  STEP(pi,pj);
467  pi+=1;
468  pj+=1;
469  if (pi==pmax)
470  pi=pmin;
471  if (pj==pmax)
472  pj=pmin;
473  }
474 
475  ir+=prm;
476  jr+=prm;
477  if (ir>=12)
478  ir-=12;
479  if (jr>=12)
480  jr-=12;
481  is=8*ir;
482  is_old=is;
483 }
484 
485 
486 static void define_constants(void)
487 {
488  int k;
489 
490  one_bit=ldexp(1.0,-24);
491 
492  for (k=0;k<96;k++)
493  {
494  next[k]=(k+1)%96;
495  if ((k%4)==3)
496  next[k]=(k+5)%96;
497  }
498 }
499 
500 
501 void rlxd_init(int level,int seed)
502 {
503  int i,k,l;
504  int ibit,jbit,xbit[31];
505  int ix,iy;
506 
507  if ((INT_MAX<2147483647)||(FLT_RADIX!=2)||(FLT_MANT_DIG<24)||
508  (DBL_MANT_DIG<48))
509  error(0);
510 
512 
513  if (level==1)
514  pr=202;
515  else if (level==2)
516  pr=397;
517  else
518  error(1);
519 
520  i=seed;
521 
522  for (k=0;k<31;k++)
523  {
524  xbit[k]=i%2;
525  i/=2;
526  }
527 
528  if ((seed<=0)||(i!=0))
529  error(2);
530 
531  ibit=0;
532  jbit=18;
533 
534  for (i=0;i<4;i++)
535  {
536  for (k=0;k<24;k++)
537  {
538  ix=0;
539 
540  for (l=0;l<24;l++)
541  {
542  iy=xbit[ibit];
543  ix=2*ix+iy;
544 
545  xbit[ibit]=(xbit[ibit]+xbit[jbit])%2;
546  ibit=(ibit+1)%31;
547  jbit=(jbit+1)%31;
548  }
549 
550  if ((k%4)!=i)
551  ix=16777215-ix;
552 
553  x.num[4*k+i]=ix;
554  }
555  }
556 
557  carry.c1=0;
558  carry.c2=0;
559  carry.c3=0;
560  carry.c4=0;
561 
562  ir=0;
563  jr=7;
564  is=91;
565  is_old=0;
566  prm=pr%12;
567  init=1;
568 }
569 
570 
571 void ranlxd(double r[],int n)
572 {
573  int k;
574 
575  if (init==0)
576  rlxd_init(1,1);
577 
578  for (k=0;k<n;k++)
579  {
580  is=next[is];
581  if (is==is_old)
582  update();
583  r[k]=one_bit*((double)(x.num[is+4])+one_bit*(double)(x.num[is]));
584  }
585 }
586 
587 
588 int rlxd_size(void)
589 {
590  return(105);
591 }
592 
593 
594 void rlxd_get(int state[])
595 {
596  int k;
597 
598  if (init==0)
599  error(3);
600 
601  state[0]=rlxd_size();
602 
603  for (k=0;k<96;k++)
604  state[k+1]=x.num[k];
605 
606  state[97]=carry.c1;
607  state[98]=carry.c2;
608  state[99]=carry.c3;
609  state[100]=carry.c4;
610 
611  state[101]=pr;
612  state[102]=ir;
613  state[103]=jr;
614  state[104]=is;
615 }
616 
617 
618 void rlxd_reset(int state[])
619 {
620  int k;
621 
622  if ((INT_MAX<2147483647)||(FLT_RADIX!=2)||(FLT_MANT_DIG<24)||
623  (DBL_MANT_DIG<48))
624  error(4);
625 
627 
628  if (state[0]!=rlxd_size())
629  error(5);
630 
631  for (k=0;k<96;k++)
632  {
633  if ((state[k+1]<0)||(state[k+1]>=167777216))
634  error(5);
635 
636  x.num[k]=state[k+1];
637  }
638 
639  if (((state[97]!=0)&&(state[97]!=1))||
640  ((state[98]!=0)&&(state[98]!=1))||
641  ((state[99]!=0)&&(state[99]!=1))||
642  ((state[100]!=0)&&(state[100]!=1)))
643  error(5);
644 
645  carry.c1=state[97];
646  carry.c2=state[98];
647  carry.c3=state[99];
648  carry.c4=state[100];
649 
650  pr=state[101];
651  ir=state[102];
652  jr=state[103];
653  is=state[104];
654  is_old=8*ir;
655  prm=pr%12;
656  init=1;
657 
658  if (((pr!=202)&&(pr!=397))||
659  (ir<0)||(ir>11)||(jr<0)||(jr>11)||(jr!=((ir+7)%12))||
660  (is<0)||(is>91))
661  error(5);
662 }
663 
664 #endif
665 
static int jr
Definition: ranlxd.cxx:374
void ranlxd(double r[], int n)
Definition: ranlxd.cxx:571
printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime)
#define STEP(pi, pj)
Definition: ranlxd.cxx:384
static int prm
Definition: ranlxd.cxx:374
void rlxd_init(int level, int seed)
Definition: ranlxd.cxx:501
double r
Definition: RiemannTest.C:14
TObjArray * d
c4
Definition: plot_dirc.C:71
int num[96]
Definition: ranlxd.cxx:381
Int_t i
Definition: run_full.C:25
TTree * b
exit(0)
static double one_bit
Definition: ranlxd.cxx:375
static void update(void)
Definition: ranlxd.cxx:453
int n
int c2
Definition: ranlxd.cxx:366
c2
Definition: plot_dirc.C:39
void rlxd_get(int state[])
Definition: ranlxd.cxx:594
#define pi
Definition: createSTT.C:60
int c4
Definition: ranlxd.cxx:366
static void error(int no)
Definition: ranlxd.cxx:419
static int init
Definition: ranlxd.cxx:374
int c3
Definition: ranlxd.cxx:366
unsigned int seed
int c1
Definition: ranlxd.cxx:366
static void define_constants(void)
Definition: ranlxd.cxx:486
int rlxd_size(void)
Definition: ranlxd.cxx:588
static int is
Definition: ranlxd.cxx:374
c1
Definition: plot_dirc.C:35
void rlxd_reset(int state[])
Definition: ranlxd.cxx:618
c3
Definition: plot_dirc.C:50
nsL1vector __attribute__
Double_t x
static int is_old
Definition: ranlxd.cxx:374
vec_t c2
Definition: ranlxd.cxx:371
static int next[96]
Definition: ranlxd.cxx:374
static vec_t carry
Definition: ranlxd.cxx:376
static int pr
Definition: ranlxd.cxx:374
dble_vec_t vec[12]
Definition: ranlxd.cxx:380
static int ir
Definition: ranlxd.cxx:374