RandomLambda.cpp
3.24 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* \file RandomLambda.cpp
* \brief Using the STL and lambda expressions with %RandomLib
*
* Compile/link with, e.g.,\n
* g++ -I../include -O2 -funroll-loops
* -o RandomLambda RandomLambda.cpp ../src/Random.cpp\n
* ./RandomLambda
*
* See \ref stl, for more information.
*
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
* under the MIT/X11 License. For more information, see
* http://randomlib.sourceforge.net/
**********************************************************************/
#include <iostream>
#include <vector>
#include <RandomLib/Random.hpp>
#include <RandomLib/NormalDistribution.hpp>
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC_MINOR__ >= 5) || \
(defined(_MSC_VER) && _MSC_VER >= 1600)
# define HAVE_LAMBDA 1
#if defined(_MSC_VER)
// Squelch warnings about nonstandard extensions
# pragma warning (disable: 4239)
#endif
#else
# define HAVE_LAMBDA 0
#endif
/// \cond SKIP
#if !HAVE_LAMBDA
// Don't need to define these if we can use lambda expressions
template<typename RealType = double> class RandomNormal {
private:
RandomLib::Random& _r;
const RandomLib::NormalDistribution<RealType> _n;
const RealType _mean, _sigma;
RandomNormal& operator=(const RandomNormal&);
public:
RandomNormal(RandomLib::Random& r,
RealType mean = RealType(0), RealType sigma = RealType(1))
: _r(r), _n(RandomLib::NormalDistribution<RealType>())
, _mean(mean), _sigma(sigma) {}
RealType operator()() { return _n(_r, _mean, _sigma); }
};
template<typename IntType = unsigned> class RandomInt {
private:
RandomLib::Random& _r;
RandomInt& operator=(const RandomInt&);
public:
RandomInt(RandomLib::Random& r)
: _r(r) {}
IntType operator()(IntType x) { return _r.Integer<IntType>(x); }
};
#endif
/// \endcond
int main(int, char**) {
RandomLib::Random r; r.Reseed();
#if HAVE_LAMBDA
std::cout << "Illustrate calling STL routines with lambda expressions\n";
#else
std::cout << "Illustrate calling STL routines without lambda expressions\n";
#endif
std::cout << "Using " << r.Name() << "\n"
<< "with seed " << r.SeedString() << "\n\n";
std::vector<unsigned> c(10); // Fill with unsigned in [0, 2^32)
#if HAVE_LAMBDA
std::generate(c.begin(), c.end(),
[&r]() throw() -> unsigned { return r(); });
#else
std::generate<std::vector<unsigned>::iterator, RandomLib::Random&>
(c.begin(), c.end(), r);
#endif
std::vector<double> b(10); // Fill with normal deviates
#if HAVE_LAMBDA
RandomLib::NormalDistribution<> nf;
std::generate(b.begin(), b.end(),
[&r, &nf]() throw() -> double
{ return nf(r,0.0,2.0); });
#else
std::generate(b.begin(), b.end(), RandomNormal<>(r,0.0,2.0));
#endif
std::vector<int> a(20); // How to shuffle large vectors
#if HAVE_LAMBDA
int i = 0;
std::generate(a.begin(), a.end(),
[&i]() throw() -> int { return i++; });
std::random_shuffle(a.begin(), a.end(),
[&r](unsigned long long n) throw() -> unsigned long long
{ return r.Integer<unsigned long long>(n); });
#else
for (size_t i = 0; i < a.size(); ++i) a[i] = int(i);
RandomInt<unsigned long long> shuffler(r);
std::random_shuffle(a.begin(), a.end(), shuffler);
#endif
return 0;
}