Commits

Kenneth Jørgensen committed 548349b

Implemented biased number generation

  • Participants
  • Parent commits c8fa56f

Comments (0)

Files changed (5)

 A collection of functions for dealing with random numbers.
 
+## Uniform random numbers
+
+* `random()`
 * `randomInteger(min, max)`
 * `randomNumber(min, max)`
+
+# Biased random numbers
+
+* `boased(bias)`
+* `biasedInteger(min, max, bias)`
+* `biasedNumber(min, max, bias)`
 {
 	"fullname": "RandomUtil",
 	"name": "random-util",
-	"version": "0.0.2",
+	"version": "0.0.3",
 	"description": "Randomness utility.",
 	"keywords": ["random", "prng"],
 	"homepage": "https://bitbucket.org/kennethjor/random-util",
 /*! RandomUtil 0.0.2 - MIT license */
 (function() {
-  var RandomUtil, exports, floor, root,
+  var RandomUtil, abs, exports, floor, pow, root,
     __hasProp = {}.hasOwnProperty;
 
   root = this;
     root["RandomUtil"] = RandomUtil;
   }
 
-  floor = Math.floor;
+  floor = Math.floor, pow = Math.pow, abs = Math.abs;
 
   RandomUtil.random = Math.random;
 
     return arr[index];
   };
 
+  RandomUtil.biased = function(bias) {
+    var r;
+    r = this.random();
+    if (bias === 0) {
+      return r;
+    }
+    if (bias < 0) {
+      return pow(r, -bias + 1);
+    }
+    if (bias > 0) {
+      return 1 - pow(1 - r, bias + 1);
+    }
+  };
+
+  RandomUtil.biasedInt = function(min, max, bias) {
+    return floor(this.biased(bias) * (max + 1 - min) + min);
+  };
+
+  RandomUtil.biasedNumber = function(min, max, bias) {
+    return this.biased() * (max - min) + min;
+  };
+
   RandomUtil.weighted = function(obj) {
     var current, i, pos, r, sum, v;
     sum = 0;

spec/RandomUtilSpec.coffee

 		expect(RandomUtil.randomNumber 10, 15).toBeCloseTo 14.5, precision
 		expect(RandomUtil.randomNumber 10, 15).toBeCloseTo 15.0, precision
 
+	it "should generate biased randoms", ->
+		increment = 0
+		state = 0.5
+		expect(RandomUtil.biased 0).toBeCloseTo 0.5, precision
+		expect(RandomUtil.biased -1).toBeCloseTo 0.25, precision
+		expect(RandomUtil.biased 1).toBeCloseTo 0.75, precision
+		expect(RandomUtil.biased -2).toBeCloseTo 0.125, precision
+		expect(RandomUtil.biased 2).toBeCloseTo 0.875, precision
+		state = 0.1
+		expect(RandomUtil.biased -1).toBeCloseTo 0.01, precision
+		expect(RandomUtil.biased -2).toBeCloseTo 0.001, precision
+		expect(RandomUtil.biased -3).toBeCloseTo 0.0001, precision
+		state = 0.9
+		expect(RandomUtil.biased 1).toBeCloseTo 0.99, precision
+		expect(RandomUtil.biased 2).toBeCloseTo 0.999, precision
+		expect(RandomUtil.biased 3).toBeCloseTo 0.9999, precision
+
+	it "should generate biased random integers"
+	it "should generate biased random numbers"
+
 	it "should select random array elements", ->
 		increment = 0.25
 		arr = "abcd".split("")

src/RandomUtil.coffee

-{floor} = Math
+{floor, pow, abs} = Math
 
 # Returns a random number between 0 and 1.
 # Replace this method to specify a custom random generator.
 	index = @randomInt 0, arr.length - 1
 	return arr[index]
 
+# Returns a biased random number.
+# `bias` is a measure of much towards the extremes the generation should be.
+# Negative bias will go towards 0, while a positive bias will go towards 1.
+RandomUtil.biased = (bias) ->
+	r = @random()
+	if bias is 0
+		return r
+	if bias < 0
+		return pow r, -bias + 1
+	if bias > 0
+		return 1 - pow 1 - r, bias + 1
+
+# Returns a random biased integer between `min` and `max`, inclusive.
+RandomUtil.biasedInt = (min, max, bias) ->
+	return floor( @biased(bias) * (max + 1 - min) + min )
+
+# Returns a random biased number between `min` and `max`.
+RandomUtil.biasedNumber = (min, max, bias) ->
+	return @biased() * (max - min) + min
+
 # Given an object with string indexes and integer weights, will return a random index based on those weights.
 #
 #     var val = RandomUtil({