~ubuntu-branches/ubuntu/trusty/libthrust/trusty

« back to all changes in this revision

Viewing changes to random/detail/subtract_with_carry_engine.inl

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Beckmann
  • Date: 2011-05-28 09:32:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110528093248-np3euv5sj7fw3nyv
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright 2008-2011 NVIDIA Corporation
 
3
 *
 
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
 
5
 *  you may not use this file except in compliance with the License.
 
6
 *  You may obtain a copy of the License at
 
7
 *
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 *  Unless required by applicable law or agreed to in writing, software
 
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 *  See the License for the specific language governing permissions and
 
14
 *  limitations under the License.
 
15
 */
 
16
 
 
17
#include <thrust/random/linear_congruential_engine.h>
 
18
#include <thrust/random/subtract_with_carry_engine.h>
 
19
#include <thrust/random/detail/mod.h>
 
20
#include <thrust/random/detail/random_core_access.h>
 
21
 
 
22
namespace thrust
 
23
{
 
24
 
 
25
namespace random
 
26
{
 
27
 
 
28
 
 
29
template<typename UIntType, size_t w, size_t s, size_t r>
 
30
  subtract_with_carry_engine<UIntType,w,s,r>
 
31
    ::subtract_with_carry_engine(result_type value)
 
32
{
 
33
  seed(value);
 
34
} // end subtract_with_carry_engine::subtract_with_carry_engine()
 
35
 
 
36
 
 
37
template<typename UIntType, size_t w, size_t s, size_t r>
 
38
  void subtract_with_carry_engine<UIntType,w,s,r>
 
39
    ::seed(result_type value)
 
40
{
 
41
  thrust::random::linear_congruential_engine<result_type,
 
42
    40014u, 0u, 2147483563u> e(value == 0u ? default_seed : value);
 
43
 
 
44
  // initialize state
 
45
  for(size_t i = 0; i < long_lag; ++i)
 
46
  {
 
47
    m_x[i] = detail::mod<UIntType, 1, 0, modulus>(e());
 
48
  } // end for i
 
49
 
 
50
  m_carry = (m_x[long_lag-1] == 0);
 
51
  m_k = 0;
 
52
} // end subtract_with_carry_engine::seed()
 
53
 
 
54
 
 
55
template<typename UIntType, size_t w, size_t s, size_t r>
 
56
  typename subtract_with_carry_engine<UIntType,w,s,r>::result_type
 
57
    subtract_with_carry_engine<UIntType,w,s,r>
 
58
      ::operator()(void)
 
59
{
 
60
  // XXX we probably need to cache these m_x[m_k] in a register
 
61
  //     maybe we need to cache the use of all member variables
 
62
  int short_index = m_k - short_lag;
 
63
  if(short_index < 0)
 
64
    short_index += long_lag;
 
65
  result_type xi;
 
66
  if (m_x[short_index] >= m_x[m_k] + m_carry)
 
67
  {
 
68
    // x(n) >= 0
 
69
    xi =  m_x[short_index] - m_x[m_k] - m_carry;
 
70
    m_carry = 0;
 
71
  }
 
72
  else
 
73
  {
 
74
    // x(n) < 0
 
75
    xi = modulus - m_x[m_k] - m_carry + m_x[short_index];
 
76
    m_carry = 1;
 
77
  }
 
78
  m_x[m_k] = xi;
 
79
  ++m_k;
 
80
  if(m_k >= long_lag)
 
81
    m_k = 0;
 
82
  return xi;
 
83
} // end subtract_with_carry_engine::operator()()
 
84
 
 
85
 
 
86
template<typename UIntType, size_t w, size_t s, size_t r>
 
87
  void subtract_with_carry_engine<UIntType,w,s,r>
 
88
    ::discard(unsigned long long z)
 
89
{
 
90
  for(; z > 0; --z)
 
91
  {
 
92
    this->operator()();
 
93
  } // end for
 
94
} // end subtract_with_carry_engine::discard()
 
95
 
 
96
 
 
97
template<typename UIntType, size_t w, size_t s, size_t r>
 
98
  template<typename CharT, typename Traits>
 
99
    std::basic_ostream<CharT,Traits>& subtract_with_carry_engine<UIntType,w,s,r>
 
100
      ::stream_out(std::basic_ostream<CharT,Traits> &os) const
 
101
{
 
102
  typedef std::basic_ostream<CharT,Traits> ostream_type;
 
103
  typedef typename ostream_type::ios_base     ios_base;
 
104
                  
 
105
  const typename ios_base::fmtflags flags = os.flags();
 
106
  const CharT fill  = os.fill();
 
107
  const CharT space = os.widen(' ');
 
108
  os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
 
109
  os.fill(space);
 
110
 
 
111
  const UIntType long_lag = r;
 
112
                                                          
 
113
  for(size_t i = 0; i < r; ++i)
 
114
    os << m_x[(i + m_k) % long_lag] << space;
 
115
  os << m_carry;
 
116
                                                                          
 
117
  os.flags(flags);
 
118
  os.fill(fill);
 
119
  return os;
 
120
}
 
121
 
 
122
 
 
123
template<typename UIntType, size_t w, size_t s, size_t r>
 
124
  template<typename CharType, typename Traits>
 
125
    std::basic_istream<CharType,Traits>& subtract_with_carry_engine<UIntType,w,s,r>
 
126
      ::stream_in(std::basic_istream<CharType,Traits> &is)
 
127
{
 
128
  typedef std::basic_istream<CharType,Traits> istream_type;
 
129
  typedef typename istream_type::ios_base     ios_base;
 
130
 
 
131
  const typename ios_base::fmtflags flags = is.flags();
 
132
  is.flags(ios_base::dec | ios_base::skipws);
 
133
 
 
134
  for(size_t i = 0; i < r; ++i)
 
135
    is >> m_x[i];
 
136
  is >> m_carry;
 
137
 
 
138
  m_k = 0;
 
139
 
 
140
  is.flags(flags);
 
141
  return is;
 
142
}
 
143
 
 
144
 
 
145
template<typename UIntType, size_t w, size_t s, size_t r>
 
146
  bool subtract_with_carry_engine<UIntType,w,s,r>
 
147
    ::equal(const subtract_with_carry_engine<UIntType,w,s,r> &rhs) const
 
148
{
 
149
  const UIntType long_lag = r;
 
150
 
 
151
  bool result = true;
 
152
  for(size_t i = 0; i < r; ++i)
 
153
  {
 
154
    result &= (m_x[(i + m_k) % long_lag] == rhs.m_x[(i + rhs.m_k) % long_lag]);
 
155
  }
 
156
 
 
157
  // XXX not sure if this last check is necessary
 
158
  result &= (m_carry == rhs.m_carry);
 
159
 
 
160
  return result;
 
161
}
 
162
 
 
163
 
 
164
template<typename UIntType, size_t w, size_t s, size_t r,
 
165
         typename CharT, typename Traits>
 
166
  std::basic_ostream<CharT,Traits>&
 
167
    operator<<(std::basic_ostream<CharT,Traits> &os,
 
168
               const subtract_with_carry_engine<UIntType,w,s,r> &e)
 
169
{
 
170
  return thrust::random::detail::random_core_access::stream_out(os,e);
 
171
}
 
172
 
 
173
 
 
174
template<typename UIntType, size_t w, size_t s, size_t r,
 
175
         typename CharType, typename Traits>
 
176
  std::basic_istream<CharType,Traits>&
 
177
    operator>>(std::basic_istream<CharType,Traits> &is,
 
178
               subtract_with_carry_engine<UIntType,w,s,r> &e)
 
179
{
 
180
  return thrust::random::detail::random_core_access::stream_in(is,e);
 
181
}
 
182
 
 
183
 
 
184
template<typename UIntType, size_t w, size_t s, size_t r>
 
185
  bool operator==(const subtract_with_carry_engine<UIntType,w,s,r> &lhs,
 
186
                  const subtract_with_carry_engine<UIntType,w,s,r> &rhs)
 
187
{
 
188
  return thrust::random::detail::random_core_access::equal(lhs,rhs);
 
189
}
 
190
 
 
191
 
 
192
template<typename UIntType, size_t w, size_t s, size_t r>
 
193
  bool operator!=(const subtract_with_carry_engine<UIntType,w,s,r> &lhs,
 
194
                  const subtract_with_carry_engine<UIntType,w,s,r> &rhs)
 
195
{
 
196
  return !(lhs == rhs);
 
197
}
 
198
 
 
199
 
 
200
} // end random
 
201
 
 
202
} // end thrust
 
203