diff options
Diffstat (limited to 'rand/rand_pcg')
-rw-r--r-- | rand/rand_pcg/CHANGELOG.md | 19 | ||||
-rw-r--r-- | rand/rand_pcg/COPYRIGHT | 12 | ||||
-rw-r--r-- | rand/rand_pcg/Cargo.toml | 37 | ||||
-rw-r--r-- | rand/rand_pcg/LICENSE-APACHE | 201 | ||||
-rw-r--r-- | rand/rand_pcg/LICENSE-MIT | 26 | ||||
-rw-r--r-- | rand/rand_pcg/README.md | 51 | ||||
-rw-r--r-- | rand/rand_pcg/build.rs | 7 | ||||
-rw-r--r-- | rand/rand_pcg/src/lib.rs | 48 | ||||
-rw-r--r-- | rand/rand_pcg/src/pcg128.rs | 122 | ||||
-rw-r--r-- | rand/rand_pcg/src/pcg64.rs | 141 | ||||
-rw-r--r-- | rand/rand_pcg/tests/lcg64xsh32.rs | 58 | ||||
-rw-r--r-- | rand/rand_pcg/tests/mcg128xsl64.rs | 59 |
12 files changed, 0 insertions, 781 deletions
diff --git a/rand/rand_pcg/CHANGELOG.md b/rand/rand_pcg/CHANGELOG.md deleted file mode 100644 index 6f793cf..0000000 --- a/rand/rand_pcg/CHANGELOG.md +++ /dev/null @@ -1,19 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [0.1.2] - unreleased -- potential blocker: https://github.com/TyOverby/bincode/issues/250 -- make `bincode` a dev-dependency again -- clean up tests and Serde support - -## [0.1.1] - 2018-10-04 -- make `bincode` an explicit dependency when using Serde - -## [0.1.0] - 2018-10-04 -Initial release, including: - -- `Lcg64Xsh32` aka `Pcg32` -- `Mcg128Xsl64` aka `Pcg64Mcg` diff --git a/rand/rand_pcg/COPYRIGHT b/rand/rand_pcg/COPYRIGHT deleted file mode 100644 index 468d907..0000000 --- a/rand/rand_pcg/COPYRIGHT +++ /dev/null @@ -1,12 +0,0 @@ -Copyrights in the Rand project are retained by their contributors. No -copyright assignment is required to contribute to the Rand project. - -For full authorship information, see the version control history. - -Except as otherwise noted (below and/or in individual files), Rand is -licensed under the Apache License, Version 2.0 <LICENSE-APACHE> or -<http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -<LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your option. - -The Rand project includes code from the Rust project -published under these same licenses. diff --git a/rand/rand_pcg/Cargo.toml b/rand/rand_pcg/Cargo.toml deleted file mode 100644 index c2fcb7d..0000000 --- a/rand/rand_pcg/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "rand_pcg" -version = "0.1.1" -authors = ["The Rand Project Developers"] -license = "MIT/Apache-2.0" -readme = "README.md" -repository = "https://github.com/rust-random/rand" -documentation = "https://rust-random.github.io/rand/rand_pcg" -homepage = "https://crates.io/crates/rand_pcg" -description = """ -Selected PCG random number generators -""" -keywords = ["random", "rng", "pcg"] -categories = ["algorithms", "no-std"] -build = "build.rs" - -[badges] -travis-ci = { repository = "rust-random/rand" } -appveyor = { repository = "rust-random/rand" } - -[features] -serde1 = ["serde", "serde_derive"] - -[dependencies] -rand_core = { path = "../rand_core", version = "0.3", default-features=false } -serde = { version = "1", optional = true } -serde_derive = { version = "^1.0.38", optional = true } - -[dev-dependencies] -# This is for testing serde, unfortunately we can't specify feature-gated dev -# deps yet, see: https://github.com/rust-lang/cargo/issues/1596 -# TODO: we shouldn't have to depend on i128 directly; it breaks tests on old -# compilers. `bincode` should automatically support this. -bincode = { version = "1", features = ["i128"] } - -[build-dependencies] -autocfg = "0.1" diff --git a/rand/rand_pcg/LICENSE-APACHE b/rand/rand_pcg/LICENSE-APACHE deleted file mode 100644 index 17d7468..0000000 --- a/rand/rand_pcg/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -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 - - https://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. diff --git a/rand/rand_pcg/LICENSE-MIT b/rand/rand_pcg/LICENSE-MIT deleted file mode 100644 index d46f058..0000000 --- a/rand/rand_pcg/LICENSE-MIT +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors -Copyright 2018 Developers of the Rand project - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/rand/rand_pcg/README.md b/rand/rand_pcg/README.md deleted file mode 100644 index 4599813..0000000 --- a/rand/rand_pcg/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# rand_pcg - -[![Build Status](https://travis-ci.org/rust-random/rand.svg?branch=master)](https://travis-ci.org/rust-random/rand) -[![Build Status](https://ci.appveyor.com/api/projects/status/github/rust-random/rand?svg=true)](https://ci.appveyor.com/project/rust-random/rand) -[![Latest version](https://img.shields.io/crates/v/rand_pcg.svg)](https://crates.io/crates/rand_pcg) -[[![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/) -[![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand_pcg) -[![API](https://docs.rs/rand_pcg/badge.svg)](https://docs.rs/rand_pcg) -[![Minimum rustc version](https://img.shields.io/badge/rustc-1.22+-lightgray.svg)](https://github.com/rust-random/rand#rust-version-requirements) - -Implements a selection of PCG random number generators. - -> PCG is a family of simple fast space-efficient statistically good algorithms -> for random number generation. [Melissa O'Neill, Harvey Mudd College, 2014]. - -The PCG algorithms are not suitable for cryptographic uses, but perform well -in statistical tests, use little memory and are fairly fast. -See the [pcg-random website](http://www.pcg-random.org/). - -This crate depends on [rand_core](https://crates.io/crates/rand_core) and is -part of the [Rand project](https://github.com/rust-random/rand). - -Links: - -- [API documentation (master)](https://rust-random.github.io/rand/rand_pcg) -- [API documentation (docs.rs)](https://docs.rs/rand_pcg) -- [Changelog](CHANGELOG.md) - - -## Crate Features - -`rand_pcg` is `no_std` compatible. It does not require any functionality -outside of the `core` lib, thus there are no features to configure. - -The `serde1` feature includes implementations of `Serialize` and `Deserialize` -for the included RNGs. NOTE: to use binary serialisation with any of the 64-bit -output (128-bit internal) RNGs, you must add the following dependency, since the -`i128` feature is not current enabled by default (this should be fixed soon): - -``` -bincode = { version = "1", features = ["i128"] } -``` - - -## License - -`rand_pcg` is distributed under the terms of both the MIT license and the -Apache License (Version 2.0). - -See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT), and -[COPYRIGHT](COPYRIGHT) for details. diff --git a/rand/rand_pcg/build.rs b/rand/rand_pcg/build.rs deleted file mode 100644 index 06e12a4..0000000 --- a/rand/rand_pcg/build.rs +++ /dev/null @@ -1,7 +0,0 @@ -extern crate autocfg; - -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - let ac = autocfg::new(); - ac.emit_rustc_version(1, 26); -} diff --git a/rand/rand_pcg/src/lib.rs b/rand/rand_pcg/src/lib.rs deleted file mode 100644 index 9648e85..0000000 --- a/rand/rand_pcg/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! The PCG random number generators. -//! -//! This is a native Rust implementation of a small selection of PCG generators. -//! The primary goal of this crate is simple, minimal, well-tested code; in -//! other words it is explicitly not a goal to re-implement all of PCG. -//! -//! This crate provides: -//! -//! - `Pcg32` aka `Lcg64Xsh32`, officially known as `pcg32`, a general -//! purpose RNG. This is a good choice on both 32-bit and 64-bit CPUs -//! (for 32-bit output). -//! - `Pcg64Mcg` aka `Mcg128Xsl64`, officially known as `mcg_xsl_rr_128_64`, -//! a general purpose RNG using 128-bit multiplications. This has poor -//! performance on 32-bit CPUs but is a good choice on 64-bit CPUs for -//! both 32-bit and 64-bit output. (Note: this RNG is only available using -//! Rust 1.26 or later.) -//! -//! Both of these use 16 bytes of state and 128-bit seeds, and are considered -//! value-stable (i.e. any change affecting the output given a fixed seed would -//! be considered a breaking change to the crate). - -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", - html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://rust-random.github.io/rand/")] - -#![deny(missing_docs)] -#![deny(missing_debug_implementations)] - -#![no_std] - -pub extern crate rand_core; - -#[cfg(feature="serde1")] extern crate serde; -#[cfg(feature="serde1")] #[macro_use] extern crate serde_derive; - -mod pcg64; -#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] mod pcg128; - -pub use self::pcg64::{Pcg32, Lcg64Xsh32}; -#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] pub use self::pcg128::{Pcg64Mcg, Mcg128Xsl64}; diff --git a/rand/rand_pcg/src/pcg128.rs b/rand/rand_pcg/src/pcg128.rs deleted file mode 100644 index 9aff506..0000000 --- a/rand/rand_pcg/src/pcg128.rs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// Copyright 2017 Paul Dicker. -// Copyright 2014-2017 Melissa O'Neill and PCG Project contributors -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! PCG random number generators - -// This is the default multiplier used by PCG for 64-bit state. -const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645; - -use core::fmt; -use core::mem::transmute; -use rand_core::{RngCore, SeedableRng, Error, le}; - -/// A PCG random number generator (XSL 128/64 (MCG) variant). -/// -/// Permuted Congruential Generator with 128-bit state, internal Multiplicative -/// Congruential Generator, and 64-bit output via "xorshift low (bits), -/// random rotation" output function. -/// -/// This is a 128-bit MCG with the PCG-XSL-RR output function. -/// Note that compared to the standard `pcg64` (128-bit LCG with PCG-XSL-RR -/// output function), this RNG is faster, also has a long cycle, and still has -/// good performance on statistical tests. -/// -/// Note: this RNG is only available using Rust 1.26 or later. -#[derive(Clone)] -#[cfg_attr(feature="serde1", derive(Serialize,Deserialize))] -pub struct Mcg128Xsl64 { - state: u128, -} - -/// A friendly name for `Mcg128Xsl64`. -pub type Pcg64Mcg = Mcg128Xsl64; - -impl Mcg128Xsl64 { - /// Construct an instance compatible with PCG seed. - /// - /// Note that PCG specifies a default value for the parameter: - /// - /// - `state = 0xcafef00dd15ea5e5` - pub fn new(state: u128) -> Self { - // Force low bit to 1, as in C version (C++ uses `state | 3` instead). - Mcg128Xsl64 { state: state | 1 } - } -} - -// Custom Debug implementation that does not expose the internal state -impl fmt::Debug for Mcg128Xsl64 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Mcg128Xsl64 {{}}") - } -} - -/// We use a single 126-bit seed to initialise the state and select a stream. -/// Two `seed` bits (lowest order of last byte) are ignored. -impl SeedableRng for Mcg128Xsl64 { - type Seed = [u8; 16]; - - fn from_seed(seed: Self::Seed) -> Self { - // Read as if a little-endian u128 value: - let mut seed_u64 = [0u64; 2]; - le::read_u64_into(&seed, &mut seed_u64); - let state = (seed_u64[0] as u128) | - (seed_u64[1] as u128) << 64; - Mcg128Xsl64::new(state) - } -} - -impl RngCore for Mcg128Xsl64 { - #[inline] - fn next_u32(&mut self) -> u32 { - self.next_u64() as u32 - } - - #[inline] - fn next_u64(&mut self) -> u64 { - // prepare the LCG for the next round - let state = self.state.wrapping_mul(MULTIPLIER); - self.state = state; - - // Output function XSL RR ("xorshift low (bits), random rotation") - // Constants are for 128-bit state, 64-bit output - const XSHIFT: u32 = 64; // (128 - 64 + 64) / 2 - const ROTATE: u32 = 122; // 128 - 6 - - let rot = (state >> ROTATE) as u32; - let xsl = ((state >> XSHIFT) as u64) ^ (state as u64); - xsl.rotate_right(rot) - } - - #[inline] - fn fill_bytes(&mut self, dest: &mut [u8]) { - // specialisation of impls::fill_bytes_via_next; approx 3x faster - let mut left = dest; - while left.len() >= 8 { - let (l, r) = {left}.split_at_mut(8); - left = r; - let chunk: [u8; 8] = unsafe { - transmute(self.next_u64().to_le()) - }; - l.copy_from_slice(&chunk); - } - let n = left.len(); - if n > 0 { - let chunk: [u8; 8] = unsafe { - transmute(self.next_u64().to_le()) - }; - left.copy_from_slice(&chunk[..n]); - } - } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) - } -} diff --git a/rand/rand_pcg/src/pcg64.rs b/rand/rand_pcg/src/pcg64.rs deleted file mode 100644 index 9177ec2..0000000 --- a/rand/rand_pcg/src/pcg64.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// Copyright 2017 Paul Dicker. -// Copyright 2014-2017 Melissa O'Neill and PCG Project contributors -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! PCG random number generators - -use core::fmt; -use core::mem::transmute; -use rand_core::{RngCore, SeedableRng, Error, le, impls}; - -// This is the default multiplier used by PCG for 64-bit state. -const MULTIPLIER: u64 = 6364136223846793005; - -/// A PCG random number generator (XSH RR 64/32 (LCG) variant). -/// -/// Permuted Congruential Generator with 64-bit state, internal Linear -/// Congruential Generator, and 32-bit output via "xorshift high (bits), -/// random rotation" output function. -/// -/// This is a 64-bit LCG with explicitly chosen stream with the PCG-XSH-RR -/// output function. This combination is the standard `pcg32`. -/// -/// Despite the name, this implementation uses 16 bytes (128 bit) space -/// comprising 64 bits of state and 64 bits stream selector. These are both set -/// by `SeedableRng`, using a 128-bit seed. -#[derive(Clone)] -#[cfg_attr(feature="serde1", derive(Serialize,Deserialize))] -pub struct Lcg64Xsh32 { - state: u64, - increment: u64, -} - -/// `Lcg64Xsh32` is also officially known as `pcg32`. -pub type Pcg32 = Lcg64Xsh32; - -impl Lcg64Xsh32 { - /// Construct an instance compatible with PCG seed and stream. - /// - /// Note that PCG specifies default values for both parameters: - /// - /// - `state = 0xcafef00dd15ea5e5` - /// - `stream = 721347520444481703` - pub fn new(state: u64, stream: u64) -> Self { - // The increment must be odd, hence we discard one bit: - let increment = (stream << 1) | 1; - Lcg64Xsh32::from_state_incr(state, increment) - } - - #[inline] - fn from_state_incr(state: u64, increment: u64) -> Self { - let mut pcg = Lcg64Xsh32 { state, increment }; - // Move away from inital value: - pcg.state = pcg.state.wrapping_add(pcg.increment); - pcg.step(); - pcg - } - - #[inline] - fn step(&mut self) { - // prepare the LCG for the next round - self.state = self.state - .wrapping_mul(MULTIPLIER) - .wrapping_add(self.increment); - } -} - -// Custom Debug implementation that does not expose the internal state -impl fmt::Debug for Lcg64Xsh32 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Lcg64Xsh32 {{}}") - } -} - -/// We use a single 127-bit seed to initialise the state and select a stream. -/// One `seed` bit (lowest bit of `seed[8]`) is ignored. -impl SeedableRng for Lcg64Xsh32 { - type Seed = [u8; 16]; - - fn from_seed(seed: Self::Seed) -> Self { - let mut seed_u64 = [0u64; 2]; - le::read_u64_into(&seed, &mut seed_u64); - - // The increment must be odd, hence we discard one bit: - Lcg64Xsh32::from_state_incr(seed_u64[0], seed_u64[1] | 1) - } -} - -impl RngCore for Lcg64Xsh32 { - #[inline] - fn next_u32(&mut self) -> u32 { - let state = self.state; - self.step(); - - // Output function XSH RR: xorshift high (bits), followed by a random rotate - // Constants are for 64-bit state, 32-bit output - const ROTATE: u32 = 59; // 64 - 5 - const XSHIFT: u32 = 18; // (5 + 32) / 2 - const SPARE: u32 = 27; // 64 - 32 - 5 - - let rot = (state >> ROTATE) as u32; - let xsh = (((state >> XSHIFT) ^ state) >> SPARE) as u32; - xsh.rotate_right(rot) - } - - #[inline] - fn next_u64(&mut self) -> u64 { - impls::next_u64_via_u32(self) - } - - #[inline] - fn fill_bytes(&mut self, dest: &mut [u8]) { - // specialisation of impls::fill_bytes_via_next; approx 40% faster - let mut left = dest; - while left.len() >= 4 { - let (l, r) = {left}.split_at_mut(4); - left = r; - let chunk: [u8; 4] = unsafe { - transmute(self.next_u32().to_le()) - }; - l.copy_from_slice(&chunk); - } - let n = left.len(); - if n > 0 { - let chunk: [u8; 4] = unsafe { - transmute(self.next_u32().to_le()) - }; - left.copy_from_slice(&chunk[..n]); - } - } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) - } -} diff --git a/rand/rand_pcg/tests/lcg64xsh32.rs b/rand/rand_pcg/tests/lcg64xsh32.rs deleted file mode 100644 index 775b12c..0000000 --- a/rand/rand_pcg/tests/lcg64xsh32.rs +++ /dev/null @@ -1,58 +0,0 @@ -extern crate rand_pcg; -extern crate rand_core; -#[cfg(all(feature="serde1", test))] extern crate bincode; - -use rand_core::{RngCore, SeedableRng}; -use rand_pcg::{Lcg64Xsh32, Pcg32}; - -#[test] -fn test_lcg64xsh32_construction() { - // Test that various construction techniques produce a working RNG. - let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; - let mut rng1 = Lcg64Xsh32::from_seed(seed); - assert_eq!(rng1.next_u64(), 1204678643940597513); - - let mut rng2 = Lcg64Xsh32::from_rng(&mut rng1).unwrap(); - assert_eq!(rng2.next_u64(), 12384929573776311845); - - let mut rng3 = Lcg64Xsh32::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 18195738587432868099); - - // This is the same as Lcg64Xsh32, so we only have a single test: - let mut rng4 = Pcg32::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 18195738587432868099); -} - -#[test] -fn test_lcg64xsh32_true_values() { - // Numbers copied from official test suite. - let mut rng = Lcg64Xsh32::new(42, 54); - - let mut results = [0u32; 6]; - for i in results.iter_mut() { *i = rng.next_u32(); } - let expected: [u32; 6] = [0xa15c02b7, 0x7b47f409, 0xba1d3330, - 0x83d2f293, 0xbfa4784b, 0xcbed606e]; - assert_eq!(results, expected); -} - -#[cfg(feature="serde1")] -#[test] -fn test_lcg64xsh32_serde() { - use bincode; - use std::io::{BufWriter, BufReader}; - - let mut rng = Lcg64Xsh32::seed_from_u64(0); - - let buf: Vec<u8> = Vec::new(); - let mut buf = BufWriter::new(buf); - bincode::serialize_into(&mut buf, &rng).expect("Could not serialize"); - - let buf = buf.into_inner().unwrap(); - let mut read = BufReader::new(&buf[..]); - let mut deserialized: Lcg64Xsh32 = bincode::deserialize_from(&mut read) - .expect("Could not deserialize"); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } -} diff --git a/rand/rand_pcg/tests/mcg128xsl64.rs b/rand/rand_pcg/tests/mcg128xsl64.rs deleted file mode 100644 index 3279536..0000000 --- a/rand/rand_pcg/tests/mcg128xsl64.rs +++ /dev/null @@ -1,59 +0,0 @@ -#![cfg(rustc_1_26)] -extern crate rand_pcg; -extern crate rand_core; -#[cfg(all(feature="serde1", test))] extern crate bincode; - -use rand_core::{RngCore, SeedableRng}; -use rand_pcg::{Mcg128Xsl64, Pcg64Mcg}; - -#[test] -fn test_mcg128xsl64_construction() { - // Test that various construction techniques produce a working RNG. - let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; - let mut rng1 = Mcg128Xsl64::from_seed(seed); - assert_eq!(rng1.next_u64(), 7071994460355047496); - - let mut rng2 = Mcg128Xsl64::from_rng(&mut rng1).unwrap(); - assert_eq!(rng2.next_u64(), 12300796107712034932); - - let mut rng3 = Mcg128Xsl64::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 6198063878555692194); - - // This is the same as Mcg128Xsl64, so we only have a single test: - let mut rng4 = Pcg64Mcg::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 6198063878555692194); -} - -#[test] -fn test_mcg128xsl64_true_values() { - // Numbers copied from official test suite (C version). - let mut rng = Mcg128Xsl64::new(42); - - let mut results = [0u64; 6]; - for i in results.iter_mut() { *i = rng.next_u64(); } - let expected: [u64; 6] = [0x63b4a3a813ce700a, 0x382954200617ab24, - 0xa7fd85ae3fe950ce, 0xd715286aa2887737, 0x60c92fee2e59f32c, 0x84c4e96beff30017]; - assert_eq!(results, expected); -} - -#[cfg(feature="serde1")] -#[test] -fn test_mcg128xsl64_serde() { - use bincode; - use std::io::{BufWriter, BufReader}; - - let mut rng = Mcg128Xsl64::seed_from_u64(0); - - let buf: Vec<u8> = Vec::new(); - let mut buf = BufWriter::new(buf); - bincode::serialize_into(&mut buf, &rng).expect("Could not serialize"); - - let buf = buf.into_inner().unwrap(); - let mut read = BufReader::new(&buf[..]); - let mut deserialized: Mcg128Xsl64 = bincode::deserialize_from(&mut read) - .expect("Could not deserialize"); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } -} |