diff --git a/Makefile.am b/Makefile.am index d90551f1..5bc472b9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -263,6 +263,8 @@ UTIL_FILES = \ quaternion.cpp \ quaternion.hpp \ raii.hpp \ + rand/xorshift.cpp \ + rand/xorshift.hpp \ random.cpp \ random.hpp \ random.ipp \ @@ -421,6 +423,7 @@ TEST_BIN = \ test/point \ test/polynomial \ test/pool \ + test/rand/xorshift \ test/random \ test/range \ test/rational \ diff --git a/rand/xorshift.cpp b/rand/xorshift.cpp new file mode 100644 index 00000000..67eb6735 --- /dev/null +++ b/rand/xorshift.cpp @@ -0,0 +1,66 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2015-2016 Danny Robson + */ + +#include "./xorshift.hpp" + +#include "../debug.hpp" + +#include + +using util::rand::xorshift; + + +/////////////////////////////////////////////////////////////////////////////// +template +xorshift::xorshift (T seed): + m_state (seed) +{ + // state must not be zero, or the period will be zero. + CHECK_NEZ (m_state); +} + + +/////////////////////////////////////////////////////////////////////////////// +namespace util { namespace rand { + template <> + uint32_t + xorshift::operator() (void) + { + m_state ^= m_state << 13u; + m_state ^= m_state >> 17u; + m_state ^= m_state << 5u; + + return m_state; + } + + + //----------------------------------------------------------------------------- + template <> + uint64_t + xorshift::operator() (void) + { + m_state ^= m_state << 13u; + m_state ^= m_state >> 7u; + m_state ^= m_state << 17u; + + return m_state; + } +} } + + +/////////////////////////////////////////////////////////////////////////////// +template struct util::rand::xorshift; +template struct util::rand::xorshift; diff --git a/rand/xorshift.hpp b/rand/xorshift.hpp new file mode 100644 index 00000000..7837c922 --- /dev/null +++ b/rand/xorshift.hpp @@ -0,0 +1,38 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2015-2016 Danny Robson + */ + +#ifndef __UTIL_RAND_XORSHIFT_HPP +#define __UTIL_RAND_XORSHIFT_HPP + +namespace util { namespace rand { + // implements a naive xorshift random generator. + // + // * does not comply with the c++11 rng class requirements + // * users may not rely on identical output across executions or library + // updates. internal constants may change across releases + template + struct xorshift { + public: + xorshift (T seed); + + T operator() (void); + + private: + T m_state; + }; +} } + +#endif