FairRoot/PandaRoot
ranlxs.cxx
Go to the documentation of this file.
1 
2 /*******************************************************************************
3 *
4 * File ranlxs.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 "ranlxs". 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 ranlxs(float r[],int n)
22 * Computes the next n single-precision random numbers and
23 * assigns them to the elements r[0],...,r[n-1] of the array r[]
24 *
25 * void rlxs_init(int level,int seed)
26 * Initialization of the generator
27 *
28 * int rlxs_size(void)
29 * Returns the number of integers required to save the state of
30 * the generator
31 *
32 * void rlxs_get(int state[])
33 * Extracts the current state of the generator and stores the
34 * information in the array state[N] where N>=rlxs_size()
35 *
36 * void rlxs_reset(int state[])
37 * Resets the generator to the state defined by the array state[N]
38 *
39 *******************************************************************************/
40 
41 #define RANLXS_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 rlxs_init\n");
109  printf("Bad choice of luxury level (should be 0,1 or 2)\n");
110  break;
111  case 2:
112  printf("Error in subroutine rlxs_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 rlxs_get\n");
117  printf("Undefined state (ranlxs is not initialized\n");
118  break;
119  case 5:
120  printf("Error in rlxs_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  next[k]=(k+1)%96;
195 }
196 
197 
198 void rlxs_init(int level,int seed)
199 {
200  int i,k,l;
201  int ibit,jbit,xbit[31];
202  int ix,iy;
203 
205 
206  if (level==0)
207  pr=109;
208  else if (level==1)
209  pr=202;
210  else if (level==2)
211  pr=397;
212  else
213  error(1);
214 
215  i=seed;
216 
217  for (k=0;k<31;k++)
218  {
219  xbit[k]=i%2;
220  i/=2;
221  }
222 
223  if ((seed<=0)||(i!=0))
224  error(2);
225 
226  ibit=0;
227  jbit=18;
228 
229  for (i=0;i<4;i++)
230  {
231  for (k=0;k<24;k++)
232  {
233  ix=0;
234 
235  for (l=0;l<24;l++)
236  {
237  iy=xbit[ibit];
238  ix=2*ix+iy;
239 
240  xbit[ibit]=(xbit[ibit]+xbit[jbit])%2;
241  ibit=(ibit+1)%31;
242  jbit=(jbit+1)%31;
243  }
244 
245  if ((k%4)==i)
246  ix=16777215-ix;
247 
248  x.num[4*k+i]=(float)(ldexp((double)(ix),-24));
249  }
250  }
251 
252  carry.c1=0.0f;
253  carry.c2=0.0f;
254  carry.c3=0.0f;
255  carry.c4=0.0f;
256 
257  ir=0;
258  jr=7;
259  is=95;
260  is_old=0;
261  prm=pr%12;
262  init=1;
263 }
264 
265 
266 void ranlxs(float r[],int n)
267 {
268  int k;
269 
270  if (init==0)
271  rlxs_init(0,1);
272 
273  for (k=0;k<n;k++)
274  {
275  is=next[is];
276  if (is==is_old)
277  update();
278  r[k]=x.num[is];
279  }
280 }
281 
282 
283 int rlxs_size(void)
284 {
285  return(105);
286 }
287 
288 
289 void rlxs_get(int state[])
290 {
291  int k;
292  float base;
293 
294  if (init==0)
295  error(3);
296 
297  base=(float)(ldexp(1.0,24));
298  state[0]=rlxs_size();
299 
300  for (k=0;k<96;k++)
301  state[k+1]=(int)(base*x.num[k]);
302 
303  state[97]=(int)(base*carry.c1);
304  state[98]=(int)(base*carry.c2);
305  state[99]=(int)(base*carry.c3);
306  state[100]=(int)(base*carry.c4);
307 
308  state[101]=pr;
309  state[102]=ir;
310  state[103]=jr;
311  state[104]=is;
312 }
313 
314 
315 void rlxs_reset(int state[])
316 {
317  int k;
318 
320 
321  if (state[0]!=rlxs_size())
322  error(5);
323 
324  for (k=0;k<96;k++)
325  {
326  if ((state[k+1]<0)||(state[k+1]>=167777216))
327  error(5);
328 
329  x.num[k]=(float)(ldexp((double)(state[k+1]),-24));
330  }
331 
332  if (((state[97]!=0)&&(state[97]!=1))||
333  ((state[98]!=0)&&(state[98]!=1))||
334  ((state[99]!=0)&&(state[99]!=1))||
335  ((state[100]!=0)&&(state[100]!=1)))
336  error(5);
337 
338  carry.c1=(float)(ldexp((double)(state[97]),-24));
339  carry.c2=(float)(ldexp((double)(state[98]),-24));
340  carry.c3=(float)(ldexp((double)(state[99]),-24));
341  carry.c4=(float)(ldexp((double)(state[100]),-24));
342 
343  pr=state[101];
344  ir=state[102];
345  jr=state[103];
346  is=state[104];
347  is_old=8*ir;
348  prm=pr%12;
349  init=1;
350 
351  if (((pr!=109)&&(pr!=202)&&(pr!=397))||
352  (ir<0)||(ir>11)||(jr<0)||(jr>11)||(jr!=((ir+7)%12))||
353  (is<0)||(is>95))
354  error(5);
355 }
356 
357 #else
358 
359 #define BASE 0x1000000
360 #define MASK 0xffffff
361 
362 typedef struct
363 {
364  int c1,c2,c3,c4;
365 } vec_t;
366 
367 typedef struct
368 {
369  vec_t c1,c2;
370 } dble_vec_t;
371 
372 static int init=0,pr,prm,ir,jr,is,is_old,next[96];
373 static float one_bit;
374 static vec_t carry;
375 
376 static union
377 {
379  int num[96];
380 } x;
381 
382 #define STEP(pi,pj) \
383  d=(*pj).c1.c1-(*pi).c1.c1-carry.c1; \
384  (*pi).c2.c1+=(d<0); \
385  d+=BASE; \
386  (*pi).c1.c1=d&MASK; \
387  d=(*pj).c1.c2-(*pi).c1.c2-carry.c2; \
388  (*pi).c2.c2+=(d<0); \
389  d+=BASE; \
390  (*pi).c1.c2=d&MASK; \
391  d=(*pj).c1.c3-(*pi).c1.c3-carry.c3; \
392  (*pi).c2.c3+=(d<0); \
393  d+=BASE; \
394  (*pi).c1.c3=d&MASK; \
395  d=(*pj).c1.c4-(*pi).c1.c4-carry.c4; \
396  (*pi).c2.c4+=(d<0); \
397  d+=BASE; \
398  (*pi).c1.c4=d&MASK; \
399  d=(*pj).c2.c1-(*pi).c2.c1; \
400  carry.c1=(d<0); \
401  d+=BASE; \
402  (*pi).c2.c1=d&MASK; \
403  d=(*pj).c2.c2-(*pi).c2.c2; \
404  carry.c2=(d<0); \
405  d+=BASE; \
406  (*pi).c2.c2=d&MASK; \
407  d=(*pj).c2.c3-(*pi).c2.c3; \
408  carry.c3=(d<0); \
409  d+=BASE; \
410  (*pi).c2.c3=d&MASK; \
411  d=(*pj).c2.c4-(*pi).c2.c4; \
412  carry.c4=(d<0); \
413  d+=BASE; \
414  (*pi).c2.c4=d&MASK
415 
416 
417 static void error(int no)
418 {
419  switch(no)
420  {
421  case 0:
422  printf("Error in rlxs_init\n");
423  printf("Arithmetic on this machine is not suitable for ranlxs\n");
424  break;
425  case 1:
426  printf("Error in subroutine rlxs_init\n");
427  printf("Bad choice of luxury level (should be 0,1 or 2)\n");
428  break;
429  case 2:
430  printf("Error in subroutine rlxs_init\n");
431  printf("Bad choice of seed (should be between 1 and 2^31-1)\n");
432  break;
433  case 3:
434  printf("Error in rlxs_get\n");
435  printf("Undefined state (ranlxs is not initialized)\n");
436  break;
437  case 4:
438  printf("Error in rlxs_reset\n");
439  printf("Arithmetic on this machine is not suitable for ranlxs\n");
440  break;
441  case 5:
442  printf("Error in rlxs_reset\n");
443  printf("Unexpected input data\n");
444  break;
445  }
446  printf("Program aborted\n");
447  exit(0);
448 }
449 
450 
451 static void update(void)
452 {
453  int k,kmax,d;
454  dble_vec_t *pmin,*pmax,*pi,*pj;
455 
456  kmax=pr;
457  pmin=&x.vec[0];
458  pmax=pmin+12;
459  pi=&x.vec[ir];
460  pj=&x.vec[jr];
461 
462  for (k=0;k<kmax;k++)
463  {
464  STEP(pi,pj);
465  pi+=1;
466  pj+=1;
467  if (pi==pmax)
468  pi=pmin;
469  if (pj==pmax)
470  pj=pmin;
471  }
472 
473  ir+=prm;
474  jr+=prm;
475  if (ir>=12)
476  ir-=12;
477  if (jr>=12)
478  jr-=12;
479  is=8*ir;
480  is_old=is;
481 }
482 
483 
484 static void define_constants(void)
485 {
486  int k;
487 
488  one_bit=(float)(ldexp(1.0,-24));
489 
490  for (k=0;k<96;k++)
491  next[k]=(k+1)%96;
492 }
493 
494 
495 void rlxs_init(int level,int seed)
496 {
497  int i,k,l;
498  int ibit,jbit,xbit[31];
499  int ix,iy;
500 
501  if ((INT_MAX<2147483647)||(FLT_RADIX!=2)||(FLT_MANT_DIG<24))
502  error(0);
503 
505 
506  if (level==0)
507  pr=109;
508  else if (level==1)
509  pr=202;
510  else if (level==2)
511  pr=397;
512  else
513  error(1);
514 
515  i=seed;
516 
517  for (k=0;k<31;k++)
518  {
519  xbit[k]=i%2;
520  i/=2;
521  }
522 
523  if ((seed<=0)||(i!=0))
524  error(2);
525 
526  ibit=0;
527  jbit=18;
528 
529  for (i=0;i<4;i++)
530  {
531  for (k=0;k<24;k++)
532  {
533  ix=0;
534 
535  for (l=0;l<24;l++)
536  {
537  iy=xbit[ibit];
538  ix=2*ix+iy;
539 
540  xbit[ibit]=(xbit[ibit]+xbit[jbit])%2;
541  ibit=(ibit+1)%31;
542  jbit=(jbit+1)%31;
543  }
544 
545  if ((k%4)==i)
546  ix=16777215-ix;
547 
548  x.num[4*k+i]=ix;
549  }
550  }
551 
552  carry.c1=0;
553  carry.c2=0;
554  carry.c3=0;
555  carry.c4=0;
556 
557  ir=0;
558  jr=7;
559  is=95;
560  is_old=0;
561  prm=pr%12;
562  init=1;
563 }
564 
565 
566 void ranlxs(float r[],int n)
567 {
568  int k;
569 
570  if (init==0)
571  rlxs_init(0,1);
572 
573  for (k=0;k<n;k++)
574  {
575  is=next[is];
576  if (is==is_old)
577  update();
578  r[k]=one_bit*(float)(x.num[is]);
579  }
580 }
581 
582 
583 int rlxs_size(void)
584 {
585  return(105);
586 }
587 
588 
589 void rlxs_get(int state[])
590 {
591  int k;
592 
593  if (init==0)
594  error(3);
595 
596  state[0]=rlxs_size();
597 
598  for (k=0;k<96;k++)
599  state[k+1]=x.num[k];
600 
601  state[97]=carry.c1;
602  state[98]=carry.c2;
603  state[99]=carry.c3;
604  state[100]=carry.c4;
605 
606  state[101]=pr;
607  state[102]=ir;
608  state[103]=jr;
609  state[104]=is;
610 }
611 
612 
613 void rlxs_reset(int state[])
614 {
615  int k;
616 
617  if ((INT_MAX<2147483647)||(FLT_RADIX!=2)||(FLT_MANT_DIG<24))
618  error(4);
619 
621 
622  if (state[0]!=rlxs_size())
623  error(5);
624 
625  for (k=0;k<96;k++)
626  {
627  if ((state[k+1]<0)||(state[k+1]>=167777216))
628  error(5);
629 
630  x.num[k]=state[k+1];
631  }
632 
633  if (((state[97]!=0)&&(state[97]!=1))||
634  ((state[98]!=0)&&(state[98]!=1))||
635  ((state[99]!=0)&&(state[99]!=1))||
636  ((state[100]!=0)&&(state[100]!=1)))
637  error(5);
638 
639  carry.c1=state[97];
640  carry.c2=state[98];
641  carry.c3=state[99];
642  carry.c4=state[100];
643 
644  pr=state[101];
645  ir=state[102];
646  jr=state[103];
647  is=state[104];
648  is_old=8*ir;
649  prm=pr%12;
650  init=1;
651 
652  if (((pr!=109)&&(pr!=202)&&(pr!=397))||
653  (ir<0)||(ir>11)||(jr<0)||(jr>11)||(jr!=((ir+7)%12))||
654  (is<0)||(is>95))
655  error(5);
656 }
657 
658 #endif
659 
printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime)
double r
Definition: RiemannTest.C:14
TObjArray * d
c4
Definition: plot_dirc.C:71
Int_t i
Definition: run_full.C:25
static float one_bit
Definition: ranlxs.cxx:373
TTree * b
exit(0)
dble_vec_t vec[12]
Definition: ranlxs.cxx:378
static int prm
Definition: ranlxs.cxx:372
int n
static int ir
Definition: ranlxs.cxx:372
int c2
Definition: ranlxd.cxx:366
c2
Definition: plot_dirc.C:39
#define pi
Definition: createSTT.C:60
static int is_old
Definition: ranlxs.cxx:372
void rlxs_get(int state[])
Definition: ranlxs.cxx:589
int c4
Definition: ranlxd.cxx:366
void rlxs_reset(int state[])
Definition: ranlxs.cxx:613
int rlxs_size(void)
Definition: ranlxs.cxx:583
static int is
Definition: ranlxs.cxx:372
static void define_constants(void)
Definition: ranlxs.cxx:484
int c3
Definition: ranlxd.cxx:366
static void error(int no)
Definition: ranlxs.cxx:417
static int jr
Definition: ranlxs.cxx:372
unsigned int seed
static vec_t carry
Definition: ranlxs.cxx:374
int c1
Definition: ranlxd.cxx:366
static union @19 x
c1
Definition: plot_dirc.C:35
void rlxs_init(int level, int seed)
Definition: ranlxs.cxx:495
c3
Definition: plot_dirc.C:50
nsL1vector __attribute__
int num[96]
Definition: ranlxs.cxx:379
static int pr
Definition: ranlxs.cxx:372
static int init
Definition: ranlxs.cxx:372
void ranlxs(float r[], int n)
Definition: ranlxs.cxx:566
static void update(void)
Definition: ranlxs.cxx:451
#define STEP(pi, pj)
Definition: ranlxs.cxx:382
static int next[96]
Definition: ranlxs.cxx:372