forked from lijiext/lammps
82 lines
2.1 KiB
C++
82 lines
2.1 KiB
C++
|
/* ----------------------------------------------------------------------
|
||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||
|
www.cs.sandia.gov/~sjplimp/lammps.html
|
||
|
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||
|
|
||
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||
|
certain rights in this software. This software is distributed under
|
||
|
the GNU General Public License.
|
||
|
|
||
|
See the README file in the top-level LAMMPS directory.
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
// Park/Miller RNG
|
||
|
|
||
|
#include "math.h"
|
||
|
#include "random_park.h"
|
||
|
|
||
|
#define IA 16807
|
||
|
#define IM 2147483647
|
||
|
#define AM (1.0/IM)
|
||
|
#define IQ 127773
|
||
|
#define IR 2836
|
||
|
|
||
|
/* ---------------------------------------------------------------------- */
|
||
|
|
||
|
RanPark::RanPark(int seed_init)
|
||
|
{
|
||
|
seed = seed_init;
|
||
|
save = 0;
|
||
|
}
|
||
|
|
||
|
/* ----------------------------------------------------------------------
|
||
|
uniform RN
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
double RanPark::uniform()
|
||
|
{
|
||
|
int k = seed/IQ;
|
||
|
seed = IA*(seed-k*IQ) - IR*k;
|
||
|
if (seed < 0) seed += IM;
|
||
|
double ans = AM*seed;
|
||
|
return ans;
|
||
|
}
|
||
|
|
||
|
/* ----------------------------------------------------------------------
|
||
|
gaussian RN
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
double RanPark::gaussian()
|
||
|
{
|
||
|
double first,v1,v2,rsq,fac;
|
||
|
|
||
|
if (!save) {
|
||
|
int again = 1;
|
||
|
while (again) {
|
||
|
v1 = 2.0*uniform()-1.0;
|
||
|
v2 = 2.0*uniform()-1.0;
|
||
|
rsq = v1*v1 + v2*v2;
|
||
|
if (rsq < 1.0 && rsq != 0.0) again = 0;
|
||
|
}
|
||
|
fac = sqrt(-2.0*log(rsq)/rsq);
|
||
|
second = v1*fac;
|
||
|
first = v2*fac;
|
||
|
save = 1;
|
||
|
} else {
|
||
|
first = second;
|
||
|
save = 0;
|
||
|
}
|
||
|
return first;
|
||
|
}
|
||
|
|
||
|
/* ----------------------------------------------------------------------
|
||
|
reset the seed to a fractional (0-1) value of the total IM
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
void RanPark::reset(double fraction)
|
||
|
{
|
||
|
seed = static_cast<int> (fraction*IM) + 1;
|
||
|
if (seed >= IM) seed = IM-1;
|
||
|
}
|