CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/ext/sfmt19937/SFMT-common.h
Views: 1401
#pragma once1/**2* @file SFMT-common.h3*4* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom5* number generator with jump function. This file includes common functions6* used in random number generation and jump.7*8* @author Mutsuo Saito (Hiroshima University)9* @author Makoto Matsumoto (The University of Tokyo)10*11* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima12* University.13* Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima14* University and The University of Tokyo.15* All rights reserved.16*17* The 3-clause BSD License is applied to this software, see18* LICENSE.txt19*/20#ifndef SFMT_COMMON_H21#define SFMT_COMMON_H2223#if defined(__cplusplus)24extern "C" {25#endif2627#include "SFMT.h"2829inline static void do_recursion(w128_t * r, w128_t * a, w128_t * b,30w128_t * c, w128_t * d);3132inline static void rshift128(w128_t *out, w128_t const *in, int shift);33inline static void lshift128(w128_t *out, w128_t const *in, int shift);3435/**36* This function simulates SIMD 128-bit right shift by the standard C.37* The 128-bit integer given in in is shifted by (shift * 8) bits.38* This function simulates the LITTLE ENDIAN SIMD.39* @param out the output of this function40* @param in the 128-bit data to be shifted41* @param shift the shift value42*/43#ifdef ONLY6444inline static void rshift128(w128_t *out, w128_t const *in, int shift) {45uint64_t th, tl, oh, ol;4647th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);48tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);4950oh = th >> (shift * 8);51ol = tl >> (shift * 8);52ol |= th << (64 - shift * 8);53out->u[0] = (uint32_t)(ol >> 32);54out->u[1] = (uint32_t)ol;55out->u[2] = (uint32_t)(oh >> 32);56out->u[3] = (uint32_t)oh;57}58#else59inline static void rshift128(w128_t *out, w128_t const *in, int shift)60{61uint64_t th, tl, oh, ol;6263th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);64tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);6566oh = th >> (shift * 8);67ol = tl >> (shift * 8);68ol |= th << (64 - shift * 8);69out->u[1] = (uint32_t)(ol >> 32);70out->u[0] = (uint32_t)ol;71out->u[3] = (uint32_t)(oh >> 32);72out->u[2] = (uint32_t)oh;73}74#endif75/**76* This function simulates SIMD 128-bit left shift by the standard C.77* The 128-bit integer given in in is shifted by (shift * 8) bits.78* This function simulates the LITTLE ENDIAN SIMD.79* @param out the output of this function80* @param in the 128-bit data to be shifted81* @param shift the shift value82*/83#ifdef ONLY6484inline static void lshift128(w128_t *out, w128_t const *in, int shift) {85uint64_t th, tl, oh, ol;8687th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);88tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);8990oh = th << (shift * 8);91ol = tl << (shift * 8);92oh |= tl >> (64 - shift * 8);93out->u[0] = (uint32_t)(ol >> 32);94out->u[1] = (uint32_t)ol;95out->u[2] = (uint32_t)(oh >> 32);96out->u[3] = (uint32_t)oh;97}98#else99inline static void lshift128(w128_t *out, w128_t const *in, int shift)100{101uint64_t th, tl, oh, ol;102103th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);104tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);105106oh = th << (shift * 8);107ol = tl << (shift * 8);108oh |= tl >> (64 - shift * 8);109out->u[1] = (uint32_t)(ol >> 32);110out->u[0] = (uint32_t)ol;111out->u[3] = (uint32_t)(oh >> 32);112out->u[2] = (uint32_t)oh;113}114#endif115/**116* This function represents the recursion formula.117* @param r output118* @param a a 128-bit part of the internal state array119* @param b a 128-bit part of the internal state array120* @param c a 128-bit part of the internal state array121* @param d a 128-bit part of the internal state array122*/123#ifdef ONLY64124inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,125w128_t *d) {126w128_t x;127w128_t y;128129lshift128(&x, a, SFMT_SL2);130rshift128(&y, c, SFMT_SR2);131r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK2) ^ y.u[0]132^ (d->u[0] << SFMT_SL1);133r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK1) ^ y.u[1]134^ (d->u[1] << SFMT_SL1);135r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK4) ^ y.u[2]136^ (d->u[2] << SFMT_SL1);137r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK3) ^ y.u[3]138^ (d->u[3] << SFMT_SL1);139}140#else141inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b,142w128_t *c, w128_t *d)143{144w128_t x;145w128_t y;146147lshift128(&x, a, SFMT_SL2);148rshift128(&y, c, SFMT_SR2);149r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK1)150^ y.u[0] ^ (d->u[0] << SFMT_SL1);151r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK2)152^ y.u[1] ^ (d->u[1] << SFMT_SL1);153r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK3)154^ y.u[2] ^ (d->u[2] << SFMT_SL1);155r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK4)156^ y.u[3] ^ (d->u[3] << SFMT_SL1);157}158#endif159#endif160161#if defined(__cplusplus)162}163#endif164165166