#random #xoroshiro #splitmix

xorshift

Implementation of the high performance xoroshiro128+, xorshift128+, xorshift1024*, and splitmix64 pseudo random number generators

4 releases

Uses old Rust 2015

0.1.3 Feb 12, 2017
0.1.2 Jan 3, 2017
0.1.1 Oct 31, 2016
0.1.0 Oct 29, 2016

#59 in #rng

Download history 81/week @ 2024-07-19 65/week @ 2024-07-26 57/week @ 2024-08-02 71/week @ 2024-08-09 60/week @ 2024-08-16 50/week @ 2024-08-23 32/week @ 2024-08-30 25/week @ 2024-09-06 32/week @ 2024-09-13 52/week @ 2024-09-20 111/week @ 2024-09-27 53/week @ 2024-10-04 38/week @ 2024-10-11 71/week @ 2024-10-18 143/week @ 2024-10-25 49/week @ 2024-11-01

305 downloads per month
Used in 7 crates (6 directly)

CC0 license

38KB
550 lines

xorshift

Rust crate implementing the high performance splitmix64, xoroshiro128+, xorshift128+, and xorshift1024* PRNGs. Derived from their respective public-domain C implementations. See COPYRIGHT for details.

Build Status crates.io page

Documentation

Algorithms

Please see http://xoroshiro.di.unimi.it for an overview of the PRNGs and their preferred use cases. For parallel simulations, xorshift1024* is recommended, otherwise xoroshiro128+. splitmix64 is convenient for seeding PRNG states.

Usage

[dependencies]
xorshift = "0.1"
extern crate xorshift;

Examples

extern crate time;
extern crate xorshift;

use time::precise_time_ns;
use xorshift::{Rand, Rng, SeedableRng, SplitMix64, Xoroshiro128, Xorshift128, Xorshift1024};

fn main() {
    // Use the high-resolution performance counter for seeding
    let now = precise_time_ns();

    // Manually seed a Xorshift128+ PRNG
    let states = [now, now];
    let mut rng: Xorshift128 = SeedableRng::from_seed(&states[..]);
    println!("Xorshift128+ random u64: {}", rng.next_u64());

    // Use a SplitMix64 PRNG to seed a Xoroshiro128+ PRNG
    let mut sm: SplitMix64 = SeedableRng::from_seed(now);
    let mut rng: Xoroshiro128 = Rand::rand(&mut sm);
    println!("Xoroshiro128+ random u64: {}", rng.next_u64());

    let mut rng: Xorshift1024 = Rand::rand(&mut sm);
    println!("Xorshift1024* random u64: {}", rng.next_u64());

    // Generate 20 random u32s
    let vals = rng.gen_iter::<u32>().take(20).collect::<Vec<u32>>();
    println!("Xorshift1024* random u32: {:?}", vals);
    
    // Generate 50 random u64s
    let vals = rng.gen_iter::<u64>().take(50).collect::<Vec<u64>>();
    println!("Xorshift1024* random u64: {:?}", vals);
}

Parallelism

Applications with little parallelism, should use the Xoroshiro128+ generator. For large scale parallel computations, use Xorshift1024*. Either use the thread_rng() function to create generators with the same seed but incremented jump states or explicitly use the jump function to forward generator state.

extern crate xorshift;

use std::thread;
use xorshift::{Rng, Xorshift1024};
use xorshift::thread_rng;

fn main() {
    let mut threads = Vec::new();

    for i in 0..17 {
        threads.push(thread::spawn(move || {
            let mut r: Xorshift1024 = thread_rng();
            println!("Thread: {}, random u64: {}", i, r.next_u64());
        }));
    }

    for child in threads {
        let _ = child.join();
    }
}
extern crate time;
extern crate xorshift;

use std::thread;
use time::precise_time_ns;
use xorshift::{Rand, Rng, RngJump, SeedableRng, SplitMix64, Xorshift1024};

fn main() {
    // Use the high-resolution performance counter for seeding
    let now = precise_time_ns();

    let mut sm: SplitMix64 = SeedableRng::from_seed(now);
    let rng: Xorshift1024 = Rand::rand(&mut sm);

    let mut threads = Vec::new();

    for i in 0..17 {
        threads.push(thread::spawn(move || {
            let mut r = rng;
            r.jump(i);
            println!("Thread: {}, random u64: {}", i, r.next_u64());
        }));
    }

    for child in threads {
        let _ = child.join();
    }
}

License

Written by Alexander Stocko and released in the Public Domain using the Creative Commons Zero Declaration.

Dependencies

~345–570KB