This commit is contained in:
2
node_modules/add/.npmignore
generated
vendored
Normal file
2
node_modules/add/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
|
||||
7
node_modules/add/.travis.yml
generated
vendored
Normal file
7
node_modules/add/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
- "0.6"
|
||||
|
||||
47
node_modules/add/Readme.md
generated
vendored
Normal file
47
node_modules/add/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# Add
|
||||
|
||||
[](https://travis-ci.org/ben-ng/add)
|
||||
|
||||
[
|
||||
](https://ci.testling.com/ben-ng/add)
|
||||
|
||||
A cross-browser, numerically stable way to add floats in Javascript. Produces a faithful rounding of the sum (the result is an immediate floating-point neighbor of the true value).
|
||||
|
||||
Algorithm: Rump-Ogita-Oishi
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var add = require('add')
|
||||
, evil = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7]
|
||||
, dumbsum = function (a,b) { return a+b }
|
||||
|
||||
console.log(evil.reduce(dumbsum)) => 15.299999999999999
|
||||
|
||||
console.log(add(evil)) => 15.3
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Ben Ng
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
36
node_modules/add/bower.json
generated
vendored
Normal file
36
node_modules/add/bower.json
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "add",
|
||||
"main": "index.js",
|
||||
"version": "2.0.5",
|
||||
"homepage": "https://github.com/ben-ng/add",
|
||||
"authors": [
|
||||
"Ben Ng <me@benng.me>"
|
||||
],
|
||||
"description": "A cross-browser, numerically stable algorithm to add floats accurately",
|
||||
"moduleType": [
|
||||
"amd",
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"numerical",
|
||||
"stable",
|
||||
"faithful",
|
||||
"rounding",
|
||||
"float",
|
||||
"error",
|
||||
"propagation",
|
||||
"summation",
|
||||
"accumulate",
|
||||
"addition",
|
||||
"numerical",
|
||||
"analysis"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test.js"
|
||||
]
|
||||
}
|
||||
177
node_modules/add/index.js
generated
vendored
Normal file
177
node_modules/add/index.js
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
(function (root, factory) {
|
||||
"use strict";
|
||||
|
||||
// AMD
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], factory);
|
||||
}
|
||||
// CommonJS
|
||||
else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
}
|
||||
// Browser
|
||||
else {
|
||||
root.add = factory();
|
||||
}
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
|
||||
// The minimum machine rounding error
|
||||
var Epsilon = Math.pow(2, -53)
|
||||
, EpsilonReciprocal = (1 / Epsilon)
|
||||
/// The smallest positive number that can be represented
|
||||
, Eta = Math.pow(2, -1074)
|
||||
// limitB is a constant used in the transform function
|
||||
, limitB = 0.5 * EpsilonReciprocal * Eta
|
||||
|
||||
/**
|
||||
* S. M. RUMP, T. OGITA AND S. OISHI
|
||||
* http://www.ti3.tu-harburg.de/paper/rump/RuOgOi07I.pdf
|
||||
*/
|
||||
|
||||
// Page 8
|
||||
// x is result, y is error
|
||||
// third is so the array is allocated for 4 spaces
|
||||
// it speeds up transform
|
||||
function fastTwoSum(a, b) {
|
||||
var x = a + b
|
||||
, q = x - a
|
||||
, y = b - q
|
||||
|
||||
return [x, y, null]
|
||||
}
|
||||
|
||||
// Page 12
|
||||
// p = q + p'
|
||||
// sigma is a power of 2 greater than or equal to |p|
|
||||
function extractScalar(sigma, p) {
|
||||
var q = (sigma + p) - sigma
|
||||
, pPrime = p - q
|
||||
|
||||
return [q, pPrime]
|
||||
}
|
||||
|
||||
// Page 12
|
||||
function extractVector(sigma, p) {
|
||||
var tau = 0.0
|
||||
, extracted
|
||||
, i = 0
|
||||
, ii = p.length
|
||||
, pPrime = new Array(ii)
|
||||
|
||||
for(; i<ii; ++i) {
|
||||
extracted = extractScalar(sigma, p[i])
|
||||
pPrime[i] = extracted[1]
|
||||
tau += extracted[0]
|
||||
}
|
||||
|
||||
return [tau, pPrime]
|
||||
}
|
||||
|
||||
// Finds the immediate power of 2 that is larger than p
|
||||
//// in a fast way
|
||||
function nextPowerTwo (p) {
|
||||
var q = EpsilonReciprocal * p
|
||||
, L = Math.abs((q + p) - q)
|
||||
|
||||
if(L === 0)
|
||||
return Math.abs(p)
|
||||
|
||||
return L
|
||||
}
|
||||
|
||||
// Helper, gets the maximum of the absolute values of an array
|
||||
function maxAbs(arr) {
|
||||
var i = 0
|
||||
, ii = arr.length
|
||||
, best = -1
|
||||
|
||||
for(; i<ii; ++i) {
|
||||
if(Math.abs(arr[i]) > best) {
|
||||
best = arr[i]
|
||||
}
|
||||
}
|
||||
|
||||
return best
|
||||
}
|
||||
|
||||
function transform (p) {
|
||||
var mu = maxAbs(p)
|
||||
, M
|
||||
, sigmaPrime
|
||||
, tPrime
|
||||
, t
|
||||
, tau
|
||||
, sigma
|
||||
, extracted
|
||||
, res
|
||||
|
||||
// Not part of the original paper, here for optimization
|
||||
, temp
|
||||
, bigPow
|
||||
, limitA
|
||||
, twoToTheM
|
||||
|
||||
if(mu === 0) {
|
||||
return [0, 0, p, 0]
|
||||
}
|
||||
|
||||
M = nextPowerTwo(p.length + 2)
|
||||
twoToTheM = Math.pow(2, M)
|
||||
bigPow = 2 * twoToTheM // equiv to Math.pow(2, 2 * M), faster
|
||||
sigmaPrime = twoToTheM * nextPowerTwo(mu)
|
||||
tPrime = 0
|
||||
|
||||
do {
|
||||
t = tPrime
|
||||
sigma = sigmaPrime
|
||||
extracted = extractVector(sigma, p)
|
||||
tau = extracted[0]
|
||||
tPrime = t + tau
|
||||
p = extracted[1]
|
||||
|
||||
if(tPrime === 0) {
|
||||
return transform(p)
|
||||
}
|
||||
|
||||
temp = Epsilon * sigma
|
||||
sigmaPrime = twoToTheM * temp
|
||||
limitA = bigPow * temp
|
||||
}
|
||||
while( Math.abs(tPrime) < limitA && sigma > limitB )
|
||||
|
||||
// res already allocated for 4
|
||||
res = fastTwoSum(t, tau)
|
||||
res[2] = p
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
function dumbSum(p) {
|
||||
var i, ii, sum = 0.0
|
||||
for(i=0, ii=p.length; i<ii; ++i) {
|
||||
sum += p[i]
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
function accSum(p) {
|
||||
|
||||
// Zero length array, or all values are zeros
|
||||
if(p.length === 0 || maxAbs(p) === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
var tfmd = transform(p)
|
||||
|
||||
return tfmd[0] + (tfmd[1] +dumbSum(tfmd[2]))
|
||||
}
|
||||
|
||||
|
||||
// exports
|
||||
accSum.dumbSum = dumbSum;
|
||||
accSum.fastTwoSum = fastTwoSum;
|
||||
accSum.nextPowerTwo = nextPowerTwo;
|
||||
return accSum;
|
||||
});
|
||||
|
||||
48
node_modules/add/package.json
generated
vendored
Normal file
48
node_modules/add/package.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "add",
|
||||
"version": "2.0.6",
|
||||
"description": "A cross-browser, numerically stable algorithm to add floats accurately",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ben-ng/add.git"
|
||||
},
|
||||
"keywords": [
|
||||
"numerically",
|
||||
"stable",
|
||||
"faithful",
|
||||
"rounding",
|
||||
"float",
|
||||
"error",
|
||||
"propagation",
|
||||
"summation",
|
||||
"accumulate",
|
||||
"addition",
|
||||
"numerical",
|
||||
"analysis"
|
||||
],
|
||||
"devDependencies": {
|
||||
"tape": "2.x.x"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test.js",
|
||||
"browsers": [
|
||||
"ie/6..latest",
|
||||
"chrome/22..latest",
|
||||
"firefox/16..latest",
|
||||
"safari/latest",
|
||||
"opera/11.0..latest",
|
||||
"iphone/6",
|
||||
"ipad/6"
|
||||
]
|
||||
},
|
||||
"author": "Ben Ng <me@benng.me>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ben-ng/add/issues"
|
||||
},
|
||||
"homepage": "https://github.com/ben-ng/add"
|
||||
}
|
||||
41
node_modules/add/test.js
generated
vendored
Normal file
41
node_modules/add/test.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Tests for numeric stability
|
||||
*/
|
||||
var algorithm = require('./')
|
||||
, test = require('tape')
|
||||
, badVector
|
||||
|
||||
badVector = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7]
|
||||
|
||||
test('fastSum', function (t) {
|
||||
t.plan(1);
|
||||
|
||||
t.deepEqual(algorithm.fastTwoSum(1/3, 1/6)
|
||||
, [0.5, -2.7755575615628914e-17, null]
|
||||
, 'Result and error should have been returned')
|
||||
});
|
||||
|
||||
test('nextPowerTwo', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
t.equal(algorithm.nextPowerTwo(1534)
|
||||
, 2048
|
||||
, 'Should be Math.pow(2, Math.ceil(algorithm.logBase2(Math.abs(1534))))')
|
||||
})
|
||||
|
||||
test('accumulate', function (t) {
|
||||
t.plan(5)
|
||||
|
||||
|
||||
t.equal(algorithm([1,2,3,4]), 10, 'Integer sum should work')
|
||||
|
||||
|
||||
t.equal(algorithm.dumbSum(badVector), 15.299999999999999, 'Inaccurate summation using naive method')
|
||||
|
||||
t.equal(algorithm(badVector), 15.3, 'Rump-Ogita-Oishi summation of insidious sum')
|
||||
|
||||
t.equal(algorithm([0, 0, 0]), 0, 'Rump-Ogita-Oishi summation of zero array')
|
||||
|
||||
t.equal(algorithm([]), 0, 'Rump-Ogita-Oishi summation of empty array')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user