deepin-ocr/3rdparty/ncnn/tests/prng.h
wangzhengyang 718c41634f feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
2022-05-10 10:22:11 +08:00

98 lines
2.5 KiB
C

/* Portable pseudorandom number generator
* Based on a 24,55 Fibonacci generator, using 55/503 rejection
* c.f.- TAoCP, 3.2.2(7), for j=24,k=55,m=2^64
*
* THIS FILE IS PUBLIC DOMAIN CODE.
*
* Written by Bob Adolf.
* Attribution is appreciated but by no means legally required.
*
* This function is sufficient for most non-crypto applications.
* It passes all but one of George Marsaglia's "diehard" randomness tests.
* (overlapping 5-tuple permutations, which is allegedly buggy)
*/
#ifndef __PRNG_H__
#define __PRNG_H__
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define LAG1 (UINT16_C(24))
#define LAG2 (UINT16_C(55))
#define RAND_SSIZE ((UINT16_C(1)) << 6)
#define RAND_SMASK (RAND_SSIZE - 1)
#define RAND_EXHAUST_LIMIT LAG2
// 10x is a heuristic, it just needs to be large enough to remove correlation
#define RAND_REFILL_COUNT ((LAG2 * 10) - RAND_EXHAUST_LIMIT)
struct prng_rand_t
{
uint64_t s[RAND_SSIZE]; // Lags
uint_fast16_t i; // Location of the current lag
uint_fast16_t c; // Exhaustion count
};
#define PRNG_RAND_MAX UINT64_MAX
static inline uint64_t prng_rand(struct prng_rand_t* state)
{
uint_fast16_t i;
uint_fast16_t r, new_rands = 0;
if (!state->c)
{ // Randomness exhausted, run forward to refill
new_rands += RAND_REFILL_COUNT + 1;
state->c = RAND_EXHAUST_LIMIT - 1;
}
else
{
new_rands = 1;
state->c--;
}
for (r = 0; r < new_rands; r++)
{
i = state->i;
state->s[i & RAND_SMASK] = state->s[(i + RAND_SSIZE - LAG1) & RAND_SMASK]
+ state->s[(i + RAND_SSIZE - LAG2) & RAND_SMASK];
state->i++;
}
return state->s[i & RAND_SMASK];
}
static inline void prng_srand(uint64_t seed, struct prng_rand_t* state)
{
uint_fast16_t i;
// Naive seed
state->c = RAND_EXHAUST_LIMIT;
state->i = 0;
state->s[0] = seed;
for (i = 1; i < RAND_SSIZE; i++)
{
// Arbitrary magic, mostly to eliminate the effect of low-value seeds.
// Probably could be better, but the run-up obviates any real need to.
state->s[i] = i * (UINT64_C(2147483647)) + seed;
}
// Run forward 10,000 numbers
for (i = 0; i < 10000; i++)
{
prng_rand(state);
}
}
// Clean up our macros
#undef LAG1
#undef LAG2
#undef RAND_SSIZE
#undef RAND_SMASK
#undef RAND_EXHAUST_LIMIT
#undef RAND_REFILL_COUNT
// PRNG_RAND_MAX is exported
#endif