1 Star 0 Fork 0

Velcon-Zheng/bowtie2

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
random_source.h 5.34 KB
一键复制 编辑 原始数据 按行查看 历史
/*
* Copyright 2011, Ben Langmead <langmea@cs.jhu.edu>
*
* This file is part of Bowtie 2.
*
* Bowtie 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Bowtie 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Bowtie 2. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RANDOM_GEN_H_
#define RANDOM_GEN_H_
#include <stdint.h>
#include "assert_helpers.h"
//#define MERSENNE_TWISTER
#ifndef MERSENNE_TWISTER
/**
* Simple pseudo-random linear congruential generator, a la Numerical
* Recipes.
*/
class RandomSource {
public:
static const uint32_t DEFUALT_A = 1664525;
static const uint32_t DEFUALT_C = 1013904223;
RandomSource() :
a(DEFUALT_A), c(DEFUALT_C), inited_(false) { }
RandomSource(uint32_t _last) :
a(DEFUALT_A), c(DEFUALT_C), last(_last), inited_(true) { }
RandomSource(uint32_t _a, uint32_t _c) :
a(_a), c(_c), inited_(false) { }
void init(uint32_t seed = 0) {
last = seed;
inited_ = true;
lastOff = 30;
}
uint32_t nextU32() {
assert(inited_);
uint32_t ret;
last = a * last + c;
ret = last >> 16;
last = a * last + c;
ret ^= last;
lastOff = 0;
return ret;
}
uint64_t nextU64() {
assert(inited_);
uint64_t first = nextU32();
first = first << 32;
uint64_t second = nextU32();
return first | second;
}
size_t nextSizeT() {
if(sizeof(size_t) == 4) {
return nextU32();
} else {
return nextU64();
}
}
/**
* Return a pseudo-random unsigned 32-bit integer sampled uniformly
* from [lo, hi].
*/
uint32_t nextU32Range(uint32_t lo, uint32_t hi) {
uint32_t ret = lo;
if(hi > lo) {
ret += (nextU32() % (hi-lo+1));
}
return ret;
}
/**
* Get next 2-bit unsigned integer.
*/
uint32_t nextU2() {
assert(inited_);
if(lastOff > 30) {
nextU32();
}
uint32_t ret = (last >> lastOff) & 3;
lastOff += 2;
return ret;
}
/**
* Get next boolean.
*/
bool nextBool() {
assert(inited_);
if(lastOff > 31) {
nextU32();
}
uint32_t ret = (last >> lastOff) & 1;
lastOff++;
return ret;
}
/**
* Return an unsigned int chosen by picking randomly from among
* options weighted by probabilies supplied as the elements of the
* 'weights' array of length 'numWeights'. The weights should add
* to 1.
*/
uint32_t nextFromProbs(
const float* weights,
size_t numWeights)
{
float f = nextFloat();
float tot = 0.0f; // total weight seen so far
for(uint32_t i = 0; i < numWeights; i++) {
tot += weights[i];
if(f < tot) return i;
}
return (uint32_t)(numWeights-1);
}
float nextFloat() {
assert(inited_);
return (float)nextU32() / (float)0xffffffff;
}
static uint32_t nextU32(uint32_t last,
uint32_t a = DEFUALT_A,
uint32_t c = DEFUALT_C)
{
return (a * last) + c;
}
uint32_t currentA() const { return a; }
uint32_t currentC() const { return c; }
uint32_t currentLast() const { return last; }
private:
uint32_t a;
uint32_t c;
uint32_t last;
uint32_t lastOff;
bool inited_;
};
#else
class RandomSource { // Mersenne Twister random number generator
public:
// default constructor: uses default seed only if this is the first instance
RandomSource() {
reset();
}
// constructor with 32 bit int as seed
RandomSource(uint32_t s) {
init(s);
}
// constructor with array of size 32 bit ints as seed
RandomSource(const uint32_t* array, int size) {
init(array, size);
}
void reset() {
state_[0] = 0;
p_ = 0;
inited_ = false;
}
virtual ~RandomSource() { }
// the two seed functions
void init(uint32_t); // seed with 32 bit integer
void init(const uint32_t*, int size); // seed with array
/**
* Return next 1-bit unsigned integer.
*/
bool nextBool() {
return (nextU32() & 1) == 0;
}
/**
* Get next unsigned 32-bit integer.
*/
inline uint32_t nextU32() {
assert(inited_);
if(p_ == n) {
gen_state(); // new state vector needed
}
// gen_state() is split off to be non-inline, because it is only called once
// in every 624 calls and otherwise irand() would become too big to get inlined
uint32_t x = state_[p_++];
x ^= (x >> 11);
x ^= (x << 7) & 0x9D2C5680UL;
x ^= (x << 15) & 0xEFC60000UL;
x ^= (x >> 18);
return x;
}
/**
* Return next float between 0 and 1.
*/
float nextFloat() {
assert(inited_);
return (float)nextU32() / (float)0xffffffff;
}
protected: // used by derived classes, otherwise not accessible; use the ()-operator
static const int n = 624, m = 397; // compile time constants
// the variables below are static (no duplicates can exist)
uint32_t state_[n]; // state vector array
int p_; // position in state array
bool inited_; // true if init function has been called
// private functions used to generate the pseudo random numbers
uint32_t twiddle(uint32_t u, uint32_t v) {
return (((u & 0x80000000UL) | (v & 0x7FFFFFFFUL)) >> 1) ^ ((v & 1UL) ? 0x9908B0DFUL : 0x0UL);
}
void gen_state(); // generate new state
};
#endif
#endif /*RANDOM_GEN_H_*/
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/Velcon-Zheng/bowtie2.git
git@gitee.com:Velcon-Zheng/bowtie2.git
Velcon-Zheng
bowtie2
bowtie2
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385