Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

95
LINES

< > BotCompany Repo | #1035196 // TripletLSFR - linear feedback shift register (repeating pseudo-RNG with a cycle length of 2^n-1, using ints)

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (10149L/56K).

// This is an LFSR (aka the XORSHIFT algorithm) which is a deterministic,
// very fast random number generator cycling through all integers
// between 1 and 2^n-1 (incl.).

sclass TripletLSFR {
  // params
  int n;
  int value = 1; // start value, but is also changed during execution
  int a, b, c; // the triplet
  
  // calculated
  gettable int cycleLength;
  
  // changing variables
  int step;
  
  // triplets table for n's from 1 to 31
  // (just the first triple that gives a full cycle, including degenerate ones,
  // so not optimized for "randomness")
  
  static final int[][] tripletsTable = {
    { 0, 0, 0 },
    { 0, 1, 1 },
    { 0, 1, 1 },
    { 0, 1, 3 },
    { 0, 1, 1 },
    { 0, 1, 1 },
    { 0, 1, 3 },
    { 1, 1, 2 },
    { 0, 1, 1 },
    { 0, 3, 7 },
    { 0, 1, 1 },
    { 1, 1, 4 },
    { 0, 1, 6 },
    { 0, 1, 1 },
    { 0, 1, 4 },
    { 1, 1, 14 },
    { 0, 3, 7 },
    { 1, 3, 14 },
    { 0, 1, 3 },
    { 1, 5, 6 },
    { 0, 1, 6 },
    { 0, 1, 21 },
    { 0, 1, 1 },
    { 1, 5, 18 },
    { 0, 1, 12 },
    { 0, 1, 1 },
    { 0, 2, 7 },
    { 0, 3, 25 },
    { 0, 1, 1 },
    { 0, 1, 1 },
    { 0, 3, 28 }
  };
  
  *(int *n) {
    if (n < 1 || n > tripletsTable.length)
      fail("Don't have triples for " + nBits(n));
    init(tripletsTable[n-1]);
  }
  
  *(int *n, int a, int b, int c) {
    init(a, b, c);
  }
  
  void init(int[] triplet) {
    init(triplet[0], triplet[1], triplet[2]);
  }
  
  void init(int a, int b, int c) {
    // handle triplets with 0s (meaning to skip one of the 3 xorshifts)
    meta-for a in a, b, c {
      this.a = a == 0 ? n : a;
    }
    
    cycleLength = (1 << n)-1;
  }
  
  int next() {
    step++;
    
    int x = value;
    x ^= (x << a) & cycleLength;
    x ^= x >>> b;
    x ^= (x << c) & cycleLength;
    ret value = x;
  }
  
  bool cycleComplete() { ret step >= cycleLength(); }
  
  // takes any integer
  selfType start aka value(int start) {
    value = mod(start, cycleLength)+1;
    this;
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035196
Snippet name: TripletLSFR - linear feedback shift register (repeating pseudo-RNG with a cycle length of 2^n-1, using ints)
Eternal ID of this version: #1035196/42
Text MD5: 1a99c53ffdc4932f7ae1cc948bc466ea
Transpilation MD5: bb0a510ac035799545269b0132483436
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-02-12 11:56:33
Source code size: 2080 bytes / 95 lines
Pitched / IR pitched: No / No
Views / Downloads: 231 / 474
Version history: 41 change(s)
Referenced in: [show references]