From dca7208fb1e1ce6910e6703fcda0f6307175766c Mon Sep 17 00:00:00 2001 From: Sebastien Piquemal Date: Sun, 4 Aug 2013 12:42:01 +0400 Subject: [PATCH] merged randomMatrix to random --- math.js | 36 ++++--- src/function/probability/random.js | 34 +++--- test/function/probability/random.js | 162 +++++++++++++++------------- 3 files changed, 132 insertions(+), 100 deletions(-) diff --git a/math.js b/math.js index 63f97f315..9796b4121 100644 --- a/math.js +++ b/math.js @@ -7,7 +7,7 @@ * mathematical functions, and a flexible expression parser. * * @version 0.11.2-SNAPSHOT - * @date 2013-08-02 + * @date 2013-08-04 * * @license * Copyright (C) 2013 Jos de Jong @@ -7552,12 +7552,27 @@ math.distribution = function(name) { var randFunctions = { - random: function(min, max) { - if (arguments.length > 2) - newArgumentsError('random', arguments.length, 0, 2); - if (max === undefined) max = 1 - if (min === undefined) min = 0 - return min + distribution() * (max - min); + random: function(arg1, arg2, arg3) { + if (arguments.length > 3) + newArgumentsError('random', arguments.length, 0, 3); + + // Random matrix + else if (Object.prototype.toString.call(arg1) === '[object Array]') { + var min = arg2, max = arg3; + if (max === undefined) max = 1; + if (min === undefined) min = 0; + return new Matrix(_randomDataForMatrix(arg1, min, max)); + + // Random float + } else { + // TODO: more precise error message? + if (arguments.length > 2) + newArgumentsError('random', arguments.length, 0, 2); + var min = arg1, max = arg2; + if (max === undefined) max = 1; + if (min === undefined) min = 0; + return min + distribution() * (max - min); + } }, randomInt: function(min, max) { @@ -7570,13 +7585,6 @@ math.distribution = function(name) { if (arguments.length !== 1) newArgumentsError('pickRandom', arguments.length, 1); return possibles[Math.floor(Math.random() * possibles.length)]; - }, - - randomMatrix: function(size, min, max) { - if (arguments.length > 3 || arguments.length < 1) - newArgumentsError('pickRandom', arguments.length, 1, 3); - debugger - return new Matrix(_randomDataForMatrix(size, min, max)); } }; diff --git a/src/function/probability/random.js b/src/function/probability/random.js index a329ffa34..d0674ff35 100644 --- a/src/function/probability/random.js +++ b/src/function/probability/random.js @@ -46,12 +46,27 @@ math.distribution = function(name) { var randFunctions = { - random: function(min, max) { - if (arguments.length > 2) - newArgumentsError('random', arguments.length, 0, 2); - if (max === undefined) max = 1 - if (min === undefined) min = 0 - return min + distribution() * (max - min); + random: function(arg1, arg2, arg3) { + if (arguments.length > 3) + newArgumentsError('random', arguments.length, 0, 3); + + // Random matrix + else if (Object.prototype.toString.call(arg1) === '[object Array]') { + var min = arg2, max = arg3; + if (max === undefined) max = 1; + if (min === undefined) min = 0; + return new Matrix(_randomDataForMatrix(arg1, min, max)); + + // Random float + } else { + // TODO: more precise error message? + if (arguments.length > 2) + newArgumentsError('random', arguments.length, 0, 2); + var min = arg1, max = arg2; + if (max === undefined) max = 1; + if (min === undefined) min = 0; + return min + distribution() * (max - min); + } }, randomInt: function(min, max) { @@ -64,13 +79,6 @@ math.distribution = function(name) { if (arguments.length !== 1) newArgumentsError('pickRandom', arguments.length, 1); return possibles[Math.floor(Math.random() * possibles.length)]; - }, - - randomMatrix: function(size, min, max) { - if (arguments.length > 3 || arguments.length < 1) - newArgumentsError('pickRandom', arguments.length, 1, 3); - debugger - return new Matrix(_randomDataForMatrix(size, min, max)); } }; diff --git a/test/function/probability/random.js b/test/function/probability/random.js index 44a98e67a..b368d1c52 100644 --- a/test/function/probability/random.js +++ b/test/function/probability/random.js @@ -8,38 +8,96 @@ var assertApproxEqual = function(testVal, val, tolerance) { else assert.ok(diff <= tolerance) } -var testRandom = function() { +var assertUniformDistribution = function(values, min, max) { + var interval = (max - min) / 10 + count = _.filter(values, function(val) { return val < min }).length + assert.equal(count, 0) + count = _.filter(values, function(val) { return val > max }).length + assert.equal(count, 0) + + count = _.filter(values, function(val) { return val < (min + interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + interval) && val < (min + 2 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 2 * interval) && val < (min + 3 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 3 * interval) && val < (min + 4 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 4 * interval) && val < (min + 5 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 5 * interval) && val < (min + 6 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 6 * interval) && val < (min + 7 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 7 * interval) && val < (min + 8 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 8 * interval) && val < (min + 9 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + count = _.filter(values, function(val) { return val >= (min + 9 * interval) }).length + assert.equal(math.round(count/values.length, 1), 0.1) + +} + +var testRandomFloat = function() { + var picked = [], count + + _.times(1000, function() { + picked.push(math.random()) + }) + assertUniformDistribution(picked, 0, 1) +} + +var testRandomFloatMinMax = function() { var picked = [], count _.times(1000, function() { picked.push(math.random(-10, 10)) }) + assertUniformDistribution(picked, -10, 10) +} - count = _.filter(picked, function(val) { return val < -10 }).length - assert.equal(count, 0) - count = _.filter(picked, function(val) { return val > 10 }).length - assert.equal(count, 0) +var testRandomMatrix = function() { + var picked = [], + matrices = [], + size = [2, 3, 4], + count, matrix - count = _.filter(picked, function(val) { return val < -8 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -8 && val < -6 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -6 && val < -4 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -4 && val < -2 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -2 && val < 0 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 0 && val < 2 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 2 && val < 4 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 4 && val < 6 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 6 && val < 8 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 8 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) + _.times(100, function() { + matrices.push(math.random(size)) + }) + + // Collect all values in one array + matrices.forEach(function(matrix) { + assert.deepEqual(matrix.size(), size) + matrix.forEach(function(val) { + picked.push(val) + }) + }) + assert.equal(picked.length, 2 * 3 * 4 * 100) + + assertUniformDistribution(picked, 0, 1) +} + +var testRandomMatrixMinMax = function() { + var picked = [], + matrices = [], + size = [2, 3, 4], + count, matrix + + _.times(100, function() { + matrices.push(math.random(size, -103, 8)) + }) + + // Collect all values in one array + matrices.forEach(function(matrix) { + assert.deepEqual(matrix.size(), size) + matrix.forEach(function(val) { + picked.push(val) + }) + }) + assert.equal(picked.length, 2 * 3 * 4 * 100) + + assertUniformDistribution(picked, -103, 8) } var testRandomInt = function() { @@ -102,52 +160,6 @@ var testPickRandom = function() { assert.equal(math.round(count/picked.length, 1), 0.2) } -var testRandomMatrix = function(size, min, max) { - var picked = [], - matrices = [], - size = [2, 3, 4], - count, matrix - - _.times(100, function() { - matrices.push(math.randomMatrix(size, -10, 10)) - }) - - // Collect all values in one array - matrices.forEach(function(matrix) { - assert.deepEqual(matrix.size(), size) - matrix.forEach(function(val) { - picked.push(val) - }) - }) - assert.equal(picked.length, 2 * 3 * 4 * 100) - - count = _.filter(picked, function(val) { return val < -10 }).length - assert.equal(count, 0) - count = _.filter(picked, function(val) { return val > 10 }).length - assert.equal(count, 0) - - count = _.filter(picked, function(val) { return val < -8 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -8 && val < -6 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -6 && val < -4 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -4 && val < -2 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= -2 && val < 0 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 0 && val < 2 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 2 && val < 4 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 4 && val < 6 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 6 && val < 8 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) - count = _.filter(picked, function(val) { return val >= 8 }).length - assert.equal(math.round(count/picked.length, 1), 0.1) -} - var testRandomNormal = function() { var picked = [], count, distribution = math.distribution('normal') @@ -171,9 +183,13 @@ var testRandomNormal = function() { assertApproxEqual(count/picked.length, 0.93, 0.01) } -testRandom() +testRandomFloat() +testRandomFloatMinMax() +testRandomMatrix() +testRandomMatrixMinMax() + + testRandomInt() testPickRandom() -testRandomMatrix() testRandomNormal() \ No newline at end of file