Repository: josdejong/mathjs
Pull request #496 (2015-10-29 03:54:52)

Replaced nthRoot algorithm with direct calculation
 Bugfix for #490


Patch:
diff --git a/HISTORY.md b/HISTORY.md
index b002f0033..b9f3b5e02 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -4,10 +4,6 @@
 ## not yet released, version 2.4.1
 
 - Fixed #480: `nthRoot` not working on Internet Explorer (up to IE 11).
-- Fixed #489: an issue with initializing a sparse matrix without data.
-  Thanks @Retsam.
-- Fixed: #493: function `combinations` did not throw an exception for 
-  non-integer values of `k`.
 
 
 ## 2015-10-09, version 2.4.0
diff --git a/lib/expression/docs/function/logical/not.js b/lib/expression/docs/function/logical/not.js
index 8655c58a8..e0b890f49 100644
--- a/lib/expression/docs/function/logical/not.js
+++ b/lib/expression/docs/function/logical/not.js
@@ -2,15 +2,16 @@ module.exports = {
   'name': 'not',
   'category': 'Logical',
   'syntax': [
+    '!x',
     'not x',
     'not(x)'
   ],
   'description': 'Logical not. Flips the boolean value of given argument.',
   'examples': [
-    'not true',
+    '!true',
     'not false',
-    'not 2',
-    'not 0'
+    '!2',
+    '!0'
   ],
   'seealso': [
     'and', 'or', 'xor'
diff --git a/lib/function/arithmetic/nthRoot.js b/lib/function/arithmetic/nthRoot.js
index 7850428b9..b6758bb60 100644
--- a/lib/function/arithmetic/nthRoot.js
+++ b/lib/function/arithmetic/nthRoot.js
@@ -238,6 +238,16 @@ function _nthRoot(a, root) {
     return inv ? 0 : a;
   }
 
+  var x = Math.pow(Math.abs(a), 1/root);
+  // If a < 0, we require that root is an odd integer,
+  // so (-1) ^ (1/root) = -1
+  x = a < 0 ? -x : x;
+  return inv ? 1 / x : x;
+
+  // Very nice algorithm, but fails with nthRoot(-2, 3).
+  // Newton's method has some well-known problems at times:
+  // https://en.wikipedia.org/wiki/Newton%27s_method#Failure_analysis
+  /*
   var x = 1; // Initial guess
   var xPrev = 1;
   var i = 0;
@@ -255,6 +265,7 @@ function _nthRoot(a, root) {
   }
 
   return inv ? 1 / x : x;
+  */
 }
 
 /**
diff --git a/lib/function/probability/combinations.js b/lib/function/probability/combinations.js
index 9b2e51aa7..8ddfe5a22 100644
--- a/lib/function/probability/combinations.js
+++ b/lib/function/probability/combinations.js
@@ -33,9 +33,6 @@ function factory (type, config, load, typed) {
       if (!isInteger(n) || n < 0) {
         throw new TypeError('Positive integer value expected in function combinations');
       }
-      if (!isInteger(k) || k < 0) {
-        throw new TypeError('Positive integer value expected in function combinations');
-      }
       if (k > n) {
         throw new TypeError('k must be less than or equal to n');
       }
diff --git a/lib/type/matrix/SparseMatrix.js b/lib/type/matrix/SparseMatrix.js
index 81a8df102..dfc0df035 100644
--- a/lib/type/matrix/SparseMatrix.js
+++ b/lib/type/matrix/SparseMatrix.js
@@ -54,7 +54,7 @@ function factory (type, config, load, typed) {
       this._values = [];
       this._index = [];
       this._ptr = [0];
-      this._size = [0, 0];
+      this._size = [0];
       this._datatype = datatype;
     }
   }
diff --git a/package.json b/package.json
index 468a1ec62..cc553cccf 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,6 @@
     "Owen Versteeg (https://github.com/owenversteeg)",
     "Pavel Panchekha (https://github.com/pavpanchekha)",
     "Pete Corey (https://github.com/pcorey)",
-    "Retsam (https://github.com/Retsam)",
     "Robert Eisele (https://github.com/infusion)",
     "Rogelio J. Baucells (https://github.com/rjbaucells)",
     "Ryan Seys (https://github.com/ryanseys)",


Test patch:
diff --git a/test/function/arithmetic/nthRoot.test.js b/test/function/arithmetic/nthRoot.test.js
index 037b8e9dc..b21d9b846 100644
--- a/test/function/arithmetic/nthRoot.test.js
+++ b/test/function/arithmetic/nthRoot.test.js
@@ -47,6 +47,8 @@ describe('nthRoot', function() {
   it('should return the nthRoot for negative numbers', function() {
     approx.equal(nthRoot(-64, 3), -4);
     approx.equal(nthRoot(-8, 3), -2);
+    // Newton's method fails in this particular case: --ericman314
+    approx.equal(nthRoot(-2, 3), -1.2599210498949);
   });
 
   it('should return the nthRoot for negative roots', function() {
diff --git a/test/function/probability/combinations.test.js b/test/function/probability/combinations.test.js
index fd609dec5..5868a9db1 100644
--- a/test/function/probability/combinations.test.js
+++ b/test/function/probability/combinations.test.js
@@ -21,10 +21,7 @@ describe('combinations', function() {
   });
 
   it('should not work with non-integer and negative input', function() {
-      assert.throws(function() {combinations(-12, 6)}, TypeError);
-      assert.throws(function() {combinations(12, -6)}, TypeError);
       assert.throws(function() {combinations(0.5, 3)}, TypeError);
-      assert.throws(function() {combinations(4, 0.5)}, TypeError);
       assert.throws(function() {combinations(3, 5)}, TypeError);
       assert.throws(function() {combinations(math.bignumber(3), math.bignumber(5))}, TypeError);
       assert.throws(function() {combinations(math.bignumber(3.5), math.bignumber(-3))}, TypeError);
diff --git a/test/function/probability/permutations.test.js b/test/function/probability/permutations.test.js
index 8cf6bbace..ba56ee9c6 100644
--- a/test/function/probability/permutations.test.js
+++ b/test/function/probability/permutations.test.js
@@ -39,9 +39,7 @@ describe('permutations', function() {
 
   it('should not accept negative or non-integer arguments', function() {
       assert.throws(function(){permutations(12, -6);}, TypeError);
-      assert.throws(function(){permutations(-12, 6);}, TypeError);
-      assert.throws(function(){permutations(4.5, 2);}, TypeError);
-      assert.throws(function(){permutations(4, 0.5);}, TypeError);
+      assert.throws(function(){permutations(-12, -6);}, TypeError);
       assert.throws(function(){permutations(math.bignumber(-12), -6);}, TypeError);
       assert.throws(function(){permutations(math.bignumber(12.5), math.bignumber(6));}, TypeError);
       assert.throws(function(){permutations(math.bignumber(12.5), math.pi);}, TypeError);
diff --git a/test/type/matrix/SparseMatrix.test.js b/test/type/matrix/SparseMatrix.test.js
index ad8e17f14..e2eb1269a 100644
--- a/test/type/matrix/SparseMatrix.test.js
+++ b/test/type/matrix/SparseMatrix.test.js
@@ -13,7 +13,7 @@ describe('SparseMatrix', function() {
 
     it('should create empty matrix if called with no argument', function() {
       var m = new SparseMatrix();
-      assert.deepEqual(m._size, [0, 0]);
+      assert.deepEqual(m._size, [0]);
       assert.deepEqual(m._values, []);
       assert.deepEqual(m._index, []);
       assert.deepEqual(m._ptr, [0]);