Git Product home page Git Product logo

suiji's Introduction

Suiji

Suiji (随机 in Chinese, /suíjī/, meaning random) is a high efficient random number generator in Typst. Partial algorithm is inherited from GSL and most APIs are similar to NumPy Random Generator. It provides pure function implementation and does not rely on any global state variables, resulting in better performance and independency.

Features

  • All functions are immutable, which means results of random are completely deterministic.
  • Core random engine chooses "Maximally equidistributed combined Tausworthe generator" and "LCG".
  • Generate random integers or floats from various distribution.
  • Randomly shuffle an array of objects.
  • Randomly sample from an array of objects.
  • Generate blind text of Simplified Chinese.

Examples

The example below uses suiji and cetz packages to create a trajectory of a random walk.

#import "@preview/suiji:0.3.0": *
#import "@preview/cetz:0.2.2"

#set page(width: auto, height: auto, margin: 0.5cm)

#cetz.canvas(length: 5pt, {
  import cetz.draw: *

  let n = 2000
  let (x, y) = (0, 0)
  let (x-new, y-new) = (0, 0)
  let rng = gen-rng(42)
  let v = ()

  for i in range(n) {
    (rng, v) = uniform(rng, low: -2.0, high: 2.0, size: 2)
    (x-new, y-new) = (x - v.at(1), y - v.at(0))
    let col = color.mix((blue.transparentize(20%), 1-i/n), (green.transparentize(20%), i/n))
    line(stroke: (paint: col, cap: "round", thickness: 2pt),
      (x, y), (x-new, y-new)
    )
    (x, y) = (x-new, y-new)
  }
})

random-walk

Another example is drawing the the famous Matrix rain effect of falling green characters in a terminal.

#import "@preview/suiji:0.3.0": *
#import "@preview/cetz:0.2.2"

#set page(width: auto, height: auto, margin: 0pt)

#cetz.canvas(length: 1pt, {
  import cetz.draw: *

  let font-size = 10
  let num-col = 80
  let num-row = 32
  let text-len = 16
  let seq = "abcdefghijklmnopqrstuvwxyz!@#$%^&*".split("").slice(1, 35).map(it => raw(it))
  let rng = gen-rng(42)
  let num-cnt = 0
  let val = 0
  let chars = ()

  rect((-10, -10), (font-size * (num-col - 1) * 0.6 + 10, font-size * (num-row - 1) + 10), fill: black)

  for c in range(num-col) {
    (rng, num-cnt) = integers(rng, low: 1, high: 3)
    for cnt in range(num-cnt) {
      (rng, val) = integers(rng, low: -10, high: num-row - 2)
      (rng, chars) = choice(rng, seq, size: text-len)
      for i in range(text-len) {
        let y = i + val
        if y >= 0 and y < num-row {
          let col = green.transparentize((i / text-len) * 100%)
          content(
            (c * font-size * 0.6, y * font-size),
            text(size: font-size * 1pt, fill:col, stroke: (text-len - i) * 0.04pt + col, chars.at(i))
          )
        }
      }
    }
  }
})

matrix-rain

Usage

Import suiji module first before use any random functions from it.

#import "@preview/suiji:0.3.0": *

For functions that generate various random numbers or randomly shuffle, a random number generator object (rng) is required as both input and output arguments. And the original rng should be created by function gen-rng, with an integer as the argument of seed. This calling style seems to be a little inconvenient, as it is limited by the programming paradigm. For function discrete, the given probalilities of the discrete events should be preprocessed by function discrete-preproc, whose output serves as an input argument of discrete.

Another set of functions with the same functionality provides higher performance (about 3 times faster) and has the suffix -f in their names. For example, gen-rng-f and integers-f are the fast versions of gen-rng and integers, respectively.

The function rand-sc creates blind text of Simplified Chinese. This function yields a Chinese-like Lorem Ipsum blind text with the given number of words, where punctuations are optional.

The code below generates several random permutations of 0 to 9. Each time after function shuffle-f is called, the value of variable rng is updated, so generated permutations are different.

#{
  let rng = gen-rng-f(42)
  let a = ()
  for i in range(5) {
    (rng, a) = shuffle-f(rng, range(10))
    [#(a.map(it => str(it)).join("  ")) \ ]
  }
}

random-permutation

For more codes with these functions see tests.

Reference

gen-rng / gen-rng-f

Construct a new random number generator with a seed.

#let gen-rng(seed) = {...}
  • Input Arguments

    • seed : [int] value of seed.
  • Output Arguments

    • rng : [object] generated object of random number generator.

randi-f

Return a raw random integer from [0, 2^31).

#let randi-f(rng) = {...}
  • Input Arguments

    • rng : [object | int] object of random number generator (generated by function *-f).
  • Output Arguments

    • rng-out : [object | int] updated object of random number generator (random integer from the interval [0, 2^31-1]).

integers / integers-f

Return random integers from low (inclusive) to high (exclusive).

#let integers(rng, low: 0, high: 100, size: none, endpoint: false) = {...}
  • Input Arguments

    • rng : [object] object of random number generator.
    • low : [int] lowest (signed) integers to be drawn from the distribution, optional.
    • high : [int] one above the largest (signed) integer to be drawn from the distribution, optional.
    • size : [none or int] returned array size, must be none or non-negative integer, optional.
    • endpoint : [bool] if true, sample from the interval [low, high] instead of the default [low, high), optional.
  • Output Arguments

    • [array] : (rng-out, arr-out)
      • rng-out : [object] updated object of random number generator.
      • arr-out : [int | array of int] array of random numbers.

random / random-f

Return random floats in the half-open interval [0.0, 1.0).

#let random(rng, size: none) = {...}
  • Input Arguments

    • rng : [object] object of random number generator.
    • size : [none or int] returned array size, must be none or non-negative integer, optional.
  • Output Arguments

    • [array] : (rng-out, arr-out)
      • rng-out : [object] updated object of random number generator.
      • arr-out : [float | array of float] array of random numbers.

uniform / uniform-f

Draw samples from a uniform distribution. Samples are uniformly distributed over the half-open interval [low, high) (includes low, but excludes high).

#let uniform(rng, low: 0.0, high: 1.0, size: none) = {...}
  • Input Arguments

    • rng : [object] object of random number generator.
    • low : [float] lower boundary of the output interval, optional.
    • high : [float] upper boundary of the output interval, optional.
    • size : [none or int] returned array size, must be none or non-negative integer, optional.
  • Output Arguments

    • [array] : (rng-out, arr-out)
      • rng-out : [object] updated object of random number generator.
      • arr-out : [float | array of float] array of random numbers.

normal / normal-f

Draw random samples from a normal (Gaussian) distribution.

#let normal(rng, loc: 0.0, scale: 1.0, size: none) = {...}
  • Input Arguments

    • rng : [object] object of random number generator.
    • loc : [float] mean (centre) of the distribution, optional.
    • scale : [float] standard deviation (spread or width) of the distribution, must be non-negative, optional.
    • size : [none or int] returned array size, must be none or non-negative integer, optional.
  • Output Arguments

    • [array] : (rng-out, arr-out)
      • rng-out : [object] updated object of random number generator.
      • arr-out : [float | array of float] array of random numbers.

discrete-preproc and discrete / discrete-preproc-f and discrete-f

Return random indices from the given probalilities of the discrete events.

#let discrete-preproc(p) = {...}
  • Input Arguments

    • p: [array of int or float] the array of probalilities of the discrete events, probalilities must be non-negative.
  • Output Arguments

    • g: [object] generated object that contains the lookup table.
#let discrete(rng, g, size: none) = {...}
  • Input Arguments

    • rng : [object] object of random number generator.
    • g : [object] generated object that contains the lookup table by discrete-preproc function.
    • size : [none or int] returned array size, must be none or non-negative integer, optional.
  • Output Arguments

    • [array] : (rng-out, arr-out)
      • rng-out : [object] updated object of random number generator.
      • arr-out : [int | array of int] array of random indices.

shuffle / shuffle-f

Randomly shuffle a given array.

#let shuffle(rng, arr) = {...}
  • Input Arguments

    • rng : [object] object of random number generator.
    • arr : [array] the array to be shuffled.
  • Output Arguments

    • [array] : (rng-out, arr-out)
      • rng-out : [object] updated object of random number generator.
      • arr-out : [array] shuffled array.

choice / choice-f

Generate random samples from a given array.

#let choice(rng, arr, size: none, replacement: true, permutation: true) = {...}
  • Input Arguments

    • rng : [object] object of random number generator.
    • arr : [array] the array to be sampled.
    • size : [none or int] returned array size, must be none or non-negative integer, optional.
    • replacement: [bool] whether the sample is with or without replacement, optional; default is true, meaning that a value of arr can be selected multiple times.
    • permutation: [bool] whether the sample is permuted when sampling without replacement, optional; default is true, false provides a speedup.
  • Output Arguments

    • [array] : (rng-out, arr-out)
      • rng-out : [object] updated object of random number generator.
      • arr-out : [array] generated random samples.

rand-sc

Generate blind text of Simplified Chinese.

#let rand-sc(words, seed: 42, punctuation: false, gap: 10) = {...}
  • Input Arguments

    • words : [int] the length of the blind text in pure words.
    • seed : [int] value of seed, optional.
    • punctuation : [bool] if true, insert punctuations in generated words, optional.
    • gap : [int] average gap between punctuations, optional.
  • Output Arguments

    • [str] : generated blind text of Simplified Chinese.

suiji's People

Contributors

liuguangxi avatar

Stargazers

ChaohongWang avatar  avatar  avatar Åsmund Olai Sand-Larsen avatar ᡥᠠᡳᡤᡳᠶᠠ ᡥᠠᠯᠠ·ᠨᡝᡴᠣ 猫 avatar F. Y. avatar  avatar Y. Xu avatar Ludwig Austermann avatar Chen avatar OrangeX4 avatar  avatar Andreas Kröpelin avatar

Watchers

 avatar

suiji's Issues

API change suggestion: Default `size` to `none` instead of `1`

Currently, if size is 1, the return value won't be an array, but directly the random value.

I suggest to change this behaviour when size is none and to always return an array when the size is an integer.

Current behaviour:

#let (rng, v) = uniform(rng, size: 1)
#repr(v)
0.18691460322588682

Suggested behaviour:

#let (rng, v) = uniform(rng)
#repr(v)
0.18691460322588682
#let (rng, v) = uniform(rng, size: 1)
#repr(v)
(0.18691460322588682,)
#let (rng, v) = uniform(rng, size: none)
#repr(v)
0.18691460322588682

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.