37 for (
int i = 1; i < d; ++i) {
38 double x = 2 * r.FixedS();
44 w += h < 1 ? sqrt(1 - h) : 0;
49 double result(
int d,
long long n,
double w) {
52 return double(1U << d) * w / double(n);
55 int usage(
const std::string& name,
int retval) {
56 ( retval == 0 ? std::cout : std::cerr )
57 <<
"Usage: \n" << name
58 <<
" [-d dim] [-n nsamp] [-k ntask] [-l stride] [-s seed] [-h]\n"
59 <<
"Estimate volume of n-dimensional unit sphere\n";
63 int main(
int argc,
char* argv[]) {
65 long long n = 10000000;
69 bool seedgiven =
false;
71 for (
int m = 1; m < argc; ++m) {
72 std::string arg(argv[m]);
74 if (++m == argc)
return usage(argv[0],
true);
75 std::istringstream str(argv[m]);
77 if (!(str >> d) || (str >> c) || d <= 0) {
78 std::cerr <<
"Number of dimensions " << argv[m]
79 <<
" is not a positive number\n";
82 }
else if (arg ==
"-n") {
83 if (++m == argc)
return usage(argv[0],
true);
84 std::istringstream str(argv[m]);
87 if (!(str >> fn) || (str >> c) || fn < 1 ||
88 fn >
double(std::numeric_limits<long long>::max())) {
89 std::cerr <<
"Total count " << argv[m] <<
" is not a positive number\n";
93 }
else if (arg ==
"-k") {
94 if (++m == argc)
return usage(argv[0],
true);
95 std::istringstream str(argv[m]);
97 if (!(str >> k) || (str >> c) || k <= 0) {
98 std::cerr <<
"Number of tasks " << argv[m]
99 <<
" is not a positive number\n";
102 }
else if (arg ==
"-l") {
103 if (++m == argc)
return usage(argv[0],
true);
104 std::istringstream str(argv[m]);
106 if (!(str >> l) || (str >> c) || l <= 0) {
107 std::cerr <<
"Leapfrog stride " << argv[m]
108 <<
" is not a positive number\n";
111 }
else if (arg ==
"-s") {
113 if (++m == argc)
return usage(argv[0], 1);
114 seedstr = std::string(argv[m]);
116 return usage(argv[0], arg !=
"-h");
119 std::vector<unsigned long> master_seed =
120 seedgiven ? Random::StringToVector(seedstr) : Random::SeedVector();
122 std::cout <<
"Estimate volume of a " << d
123 <<
"-dimensional sphere;\nsamples = -n " << n
124 <<
"; tasks = -k " << k
125 <<
"; leapfrog stride = -l " << l <<
";\nusing " << Random::Name()
126 <<
"\nwith master seed = -s "
127 << Random::VectorToString(master_seed) <<
".\n";
128 std::cout <<
"Estimated volume = "
129 << std::fixed << std::setprecision(8) << std::flush;
132 master_seed.push_back(0);
134 std::vector<double> w(k, std::numeric_limits<double>::quiet_NaN());
137 #pragma omp parallel for
139 for (
int i = 0; i < k; ++i) {
142 std::vector<unsigned long> seed(master_seed);
146 r.SetStride(l, i % l);
149 w[i] =
dotrials(r, d, (n * (i + 1))/k - (n * i)/k);
152 double weight = accumulate(w.begin(), w.end(), 0.0);
154 std::cout <<
result(d, n, weight) <<
"\n";
double result(int d, long long n, double w)
Header for Random, RandomGenerator.
int main(int argc, char *argv[])
int usage(const std::string &name, int retval)
RandomCanonical< RandomGenerator > Random
double dotrials(Random &r, int d, long long n)