Procházet zdrojové kódy

Added Random.Xoshiro.

Brucey před 5 roky
rodič
revize
5fb0a31270
2 změnil soubory, kde provedl 192 přidání a 0 odebrání
  1. 70 0
      xoshiro.mod/src/xoshiro256plusplus.c
  2. 122 0
      xoshiro.mod/xoshiro.bmx

+ 70 - 0
xoshiro.mod/src/xoshiro256plusplus.c

@@ -0,0 +1,70 @@
+
+/*  Written in 2019 by David Blackman and Sebastiano Vigna ([email protected])
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See <http://creativecommons.org/publicdomain/zero/1.0/>. */
+
+#include <stdint.h>
+#include <stdio.h>
+
+/* This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
+   It has excellent (sub-ns) speed, a state (256 bits) that is large
+   enough for any parallel application, and it passes all tests we are
+   aware of.
+
+   For generating just floating-point numbers, xoshiro256+ is even faster.
+
+   The state must be seeded so that it is not everywhere zero. If you have
+   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
+   output to fill s. */
+
+typedef struct rng_state {
+	uint64_t s[4];
+} rng_state;
+   
+static inline uint64_t rotl(const uint64_t x, int k) {
+	return (x << k) | (x >> (64 - k));
+}
+
+static inline uint64_t splitmix(uint64_t * x) {
+	uint64_t z = (*x += 0x9e3779b97f4a7c15);
+	z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
+	z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
+	return z ^ (z >> 31);
+}
+
+static inline double uint64_to_double(uint64_t v) {
+	return (v >> 11) * (1.0/9007199254740992.0);
+}
+
+void bmx_xoshiro_seed(uint64_t seed, rng_state * state) {
+	uint64_t x = seed;
+	state->s[0] = splitmix(&x);
+	state->s[1] = splitmix(&x);
+	state->s[2] = splitmix(&x);
+	state->s[3] = splitmix(&x);
+}
+
+uint64_t bmx_xoshiro_next(rng_state * state) {
+	const uint64_t result = rotl(state->s[0] + state->s[3], 23) + state->s[0];
+
+	const uint64_t t = state->s[1] << 17;
+
+	state->s[2] ^= state->s[0];
+	state->s[3] ^= state->s[1];
+	state->s[1] ^= state->s[2];
+	state->s[0] ^= state->s[3];
+
+	state->s[2] ^= t;
+
+	state->s[3] = rotl(state->s[3], 45);
+
+	return result;
+}
+
+double bmx_xoshiro_next_double(rng_state * state) {
+	return uint64_to_double(bmx_xoshiro_next(state));
+}

+ 122 - 0
xoshiro.mod/xoshiro.bmx

@@ -0,0 +1,122 @@
+' Copyright (c) 2020 Bruce A Henderson
+'
+' This software is provided 'as-is', without any express or implied
+' warranty. In no event will the authors be held liable for any damages
+' arising from the use of this software.
+'
+' Permission is granted to anyone to use this software for any purpose,
+' including commercial applications, and to alter it and redistribute it
+' freely, subject to the following restrictions:
+'
+'    1. The origin of this software must not be misrepresented; you must not
+'    claim that you wrote the original software. If you use this software
+'    in a product, an acknowledgment in the product documentation would be
+'    appreciated but is not required.
+'
+'    2. Altered source versions must be plainly marked as such, and must not be
+'    misrepresented as being the original software.
+'
+'    3. This notice may not be removed or altered from any source
+'    distribution.
+'
+SuperStrict
+
+Rem
+bbdoc: Random Numbers - Xoshiro
+End Rem
+Module Random.Xoshiro
+
+ModuleInfo "Version: 1.00"
+ModuleInfo "License: zlib"
+ModuleInfo "Copyright: Wrapper - 2020 Bruce A Henderson"
+ModuleInfo "Copyright: xoshiro256++ - 2019 David Blackman and Sebastiano Vigna"
+
+ModuleInfo "History: 1.00"
+ModuleInfo "History: Initial Release."
+
+Import BRL.Random
+Import "src/xoshiro256plusplus.c"
+
+Type TXoshiroRandom Extends TRandom
+	
+	Private
+	
+	Field rnd_state:SState
+	Field rnd_seed:Int
+	
+	Public
+	
+	Method New()
+		SeedRnd(GenerateSeed())
+	End Method
+	
+	Method New(seed:Int)
+		SeedRnd seed
+	End Method
+	
+	Method RndFloat:Float()
+		Return Float(RndDouble())
+	End Method
+	
+	Method RndDouble:Double()
+		Return bmx_xoshiro_next_double(rnd_state)
+	End Method
+	
+	Method Rnd:Double(minValue:Double = 1, maxValue:Double = 0)
+		If maxValue > minValue Return RndDouble() * (maxValue - minValue) + minValue
+		Return RndDouble() * (minValue - maxValue) + maxValue
+	End Method
+	
+	Method Rand:Int(minValue:Int, maxValue:Int = 1)
+		Local Range:Double = maxValue - minValue
+		If Range > 0 Return Int( bmx_xoshiro_next_double(rnd_state)*(1:Double+Range) )+minValue
+		Return Int( bmx_xoshiro_next_double(rnd_state)*(1:Double-Range) )+maxValue
+	End Method
+	
+	Method SeedRnd(seed:Int)
+		rnd_seed = seed
+		If seed = 0 Then
+			seed = $1234
+		End If
+		bmx_xoshiro_seed(ULong(seed), rnd_state)
+	End Method
+	
+	Method RndSeed:Int()
+		Return rnd_seed
+	End Method
+
+End Type
+
+Private
+Type TXoshiroRandomFactory Extends TRandomFactory
+	
+	Method New()
+		Super.New()
+		Init()
+	End Method
+	
+	Method GetName:String()
+		Return "Xoshiro"
+	End Method
+	
+	Method Create:TRandom(seed:Int)
+		Return New TXoshiroRandom(seed)
+	End Method
+
+	Method Create:TRandom()
+		Return New TXoshiroRandom()
+	End Method
+		
+End Type
+
+Struct SState
+	Field StaticArray rnd_state:ULong[4]
+End Struct
+
+Extern
+	Function bmx_xoshiro_seed(seed:ULong, state:SState Var)
+	Function bmx_xoshiro_next:ULong(state:SState Var)
+	Function bmx_xoshiro_next_double:Double(state:SState Var)
+End Extern
+
+New TXoshiroRandomFactory