os/ossrv/ossrv_pub/boost_apis/boost/random/additive_combine.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* boost random/additive_combine.hpp header file
sl@0
     2
 *
sl@0
     3
 * Copyright Jens Maurer 2000-2001
sl@0
     4
 * Distributed under the Boost Software License, Version 1.0. (See
sl@0
     5
 * accompanying file LICENSE_1_0.txt or copy at
sl@0
     6
 * http://www.boost.org/LICENSE_1_0.txt)
sl@0
     7
 *
sl@0
     8
 * See http://www.boost.org for most recent version including documentation.
sl@0
     9
 *
sl@0
    10
 * $Id: additive_combine.hpp,v 1.11 2005/05/21 15:57:00 dgregor Exp $
sl@0
    11
 *
sl@0
    12
 * Revision history
sl@0
    13
 *  2001-02-18  moved to individual header files
sl@0
    14
 */
sl@0
    15
sl@0
    16
#ifndef BOOST_RANDOM_ADDITIVE_COMBINE_HPP
sl@0
    17
#define BOOST_RANDOM_ADDITIVE_COMBINE_HPP
sl@0
    18
sl@0
    19
#include <iostream>
sl@0
    20
#include <algorithm> // for std::min and std::max
sl@0
    21
#include <boost/config.hpp>
sl@0
    22
#include <boost/cstdint.hpp>
sl@0
    23
#include <boost/random/linear_congruential.hpp>
sl@0
    24
sl@0
    25
namespace boost {
sl@0
    26
namespace random {
sl@0
    27
sl@0
    28
// L'Ecuyer 1988
sl@0
    29
template<class MLCG1, class MLCG2,
sl@0
    30
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
sl@0
    31
  typename MLCG1::result_type 
sl@0
    32
#else
sl@0
    33
  int32_t
sl@0
    34
#endif
sl@0
    35
  val>
sl@0
    36
class additive_combine
sl@0
    37
{
sl@0
    38
public:
sl@0
    39
  typedef MLCG1 first_base;
sl@0
    40
  typedef MLCG2 second_base;
sl@0
    41
  typedef typename MLCG1::result_type result_type;
sl@0
    42
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
sl@0
    43
  static const bool has_fixed_range = true;
sl@0
    44
  static const result_type min_value = 1;
sl@0
    45
  static const result_type max_value = MLCG1::max_value-1;
sl@0
    46
#else
sl@0
    47
  enum { has_fixed_range = false };
sl@0
    48
#endif
sl@0
    49
  result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 1; }
sl@0
    50
  result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_mlcg1.max)()-1; }
sl@0
    51
sl@0
    52
  additive_combine() : _mlcg1(), _mlcg2() { }
sl@0
    53
  additive_combine(typename MLCG1::result_type seed1, 
sl@0
    54
                   typename MLCG2::result_type seed2)
sl@0
    55
    : _mlcg1(seed1), _mlcg2(seed2) { }
sl@0
    56
  template<class It> additive_combine(It& first, It last)
sl@0
    57
    : _mlcg1(first, last), _mlcg2(first, last) { }
sl@0
    58
sl@0
    59
  void seed()
sl@0
    60
  {
sl@0
    61
    _mlcg1.seed();
sl@0
    62
    _mlcg2.seed();
sl@0
    63
  }
sl@0
    64
sl@0
    65
  void seed(typename MLCG1::result_type seed1,
sl@0
    66
            typename MLCG2::result_type seed2)
sl@0
    67
  {
sl@0
    68
    _mlcg1(seed1);
sl@0
    69
    _mlcg2(seed2);
sl@0
    70
  }
sl@0
    71
sl@0
    72
  template<class It> void seed(It& first, It last)
sl@0
    73
  {
sl@0
    74
    _mlcg1.seed(first, last);
sl@0
    75
    _mlcg2.seed(first, last);
sl@0
    76
  }
sl@0
    77
sl@0
    78
  result_type operator()() {
sl@0
    79
    result_type z = _mlcg1() - _mlcg2();
sl@0
    80
    if(z < 1)
sl@0
    81
      z += MLCG1::modulus-1;
sl@0
    82
    return z;
sl@0
    83
  }
sl@0
    84
  static bool validation(result_type x) { return val == x; }
sl@0
    85
sl@0
    86
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
sl@0
    87
sl@0
    88
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
sl@0
    89
  template<class CharT, class Traits>
sl@0
    90
  friend std::basic_ostream<CharT,Traits>&
sl@0
    91
  operator<<(std::basic_ostream<CharT,Traits>& os, const additive_combine& r)
sl@0
    92
  { os << r._mlcg1 << " " << r._mlcg2; return os; }
sl@0
    93
sl@0
    94
  template<class CharT, class Traits>
sl@0
    95
  friend std::basic_istream<CharT,Traits>&
sl@0
    96
  operator>>(std::basic_istream<CharT,Traits>& is, additive_combine& r)
sl@0
    97
  { is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; }
sl@0
    98
#endif
sl@0
    99
sl@0
   100
  friend bool operator==(const additive_combine& x, const additive_combine& y)
sl@0
   101
  { return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; }
sl@0
   102
  friend bool operator!=(const additive_combine& x, const additive_combine& y)
sl@0
   103
  { return !(x == y); }
sl@0
   104
#else
sl@0
   105
  // Use a member function; Streamable concept not supported.
sl@0
   106
  bool operator==(const additive_combine& rhs) const
sl@0
   107
  { return _mlcg1 == rhs._mlcg1 && _mlcg2 == rhs._mlcg2; }
sl@0
   108
  bool operator!=(const additive_combine& rhs) const
sl@0
   109
  { return !(*this == rhs); }
sl@0
   110
#endif
sl@0
   111
private:
sl@0
   112
  MLCG1 _mlcg1;
sl@0
   113
  MLCG2 _mlcg2;
sl@0
   114
};
sl@0
   115
sl@0
   116
} // namespace random
sl@0
   117
sl@0
   118
typedef random::additive_combine<
sl@0
   119
    random::linear_congruential<int32_t, 40014, 0, 2147483563, 0>,
sl@0
   120
    random::linear_congruential<int32_t, 40692, 0, 2147483399, 0>,
sl@0
   121
  2060321752> ecuyer1988;
sl@0
   122
sl@0
   123
} // namespace boost
sl@0
   124
sl@0
   125
#endif // BOOST_RANDOM_ADDITIVE_COMBINE_HPP