diff --git a/lib/function/matrix/inv.js b/lib/function/matrix/inv.js index c1cdac9fc..f288d8d93 100644 --- a/lib/function/matrix/inv.js +++ b/lib/function/matrix/inv.js @@ -60,7 +60,8 @@ module.exports = function (math) { if (rows == cols) { if (x instanceof Matrix) { return math.matrix( - _inv(x.valueOf(), rows, cols) + _inv(x.valueOf(), rows, cols), + x.storage() ); } else { diff --git a/lib/type/matrix/CcsMatrix.js b/lib/type/matrix/CcsMatrix.js index 44faaf715..f1a1ff110 100644 --- a/lib/type/matrix/CcsMatrix.js +++ b/lib/type/matrix/CcsMatrix.js @@ -834,7 +834,7 @@ module.exports = function (math) { * * @param {Array} size The matrix size. * @param {Number, Array} value The values for the diagonal. - * @param {Number} [defaultValue] The default value for non-diagonal + * @param {Number | BigNumber} [k=0] The diagonal where the vector will be filled in. * * @returns {CcsMatrix} */ @@ -857,13 +857,31 @@ module.exports = function (math) { } return s; }); + + // validate k if any + if (k) { + // convert BigNumber to a number + if (k instanceof BigNumber) + k = k.toNumber(); + // is must be an integer + if (!isNumber(k) || !isInteger(k)) { + throw new TypeError ('The parameter k must be an integer number'); + } + } + else { + // default value + k = 0; + } + var kSuper = k > 0 ? k : 0; + var kSub = k < 0 ? -k : 0; + // rows and columns var rows = size[0]; var columns = size[1]; // number of non-zero items - var n = Math.min(rows, columns); + var n = Math.min(rows - kSub, columns - kSuper); // value extraction function var _value; @@ -895,17 +913,19 @@ module.exports = function (math) { var ptr = []; // loop items - for (var i = 0; i < columns; i++) { + for (var j = 0; j < columns; j++) { // number of rows with value ptr.push(values.length); + // diagonal index + var i = j - kSuper; // check we need to set diagonal value - if (i < n) { + if (i >= 0 && i < n) { // get value @ i var v = _value(i); // check for zero if (!math.equal(v, 0)) { // column - index.push(i); + index.push(i + kSub); // add value values.push(v); } diff --git a/test/function/matrix/inv.test.js b/test/function/matrix/inv.test.js index 26b3c887c..d8ead7a3c 100644 --- a/test/function/matrix/inv.test.js +++ b/test/function/matrix/inv.test.js @@ -56,7 +56,8 @@ describe('inv', function() { it('should return the inverse for each element in a matrix', function() { assert.deepEqual(inv(math.matrix([4])), math.matrix([1/4])); assert.deepEqual(inv(math.matrix([[4]])), math.matrix([[1/4]])); - assert.deepEqual(inv(math.matrix([[1,2],[3,4]])), math.matrix([[-2, 1],[1.5, -0.5]])); + assert.deepEqual(inv(math.matrix([[4]], 'ccs')), math.matrix([[1/4]], 'ccs')); + assert.deepEqual(inv(math.matrix([[1,2],[3,4]], 'ccs')), math.matrix([[-2, 1],[1.5, -0.5]], 'ccs')); }); it('should throw an error in case of non-square matrices', function() { diff --git a/test/type/matrix/CcsMatrix.test.js b/test/type/matrix/CcsMatrix.test.js index eb90639d7..dde1c00a1 100644 --- a/test/type/matrix/CcsMatrix.test.js +++ b/test/type/matrix/CcsMatrix.test.js @@ -1224,6 +1224,96 @@ describe('CcsMatrix', function() { ]); }); + it('should create CCS matrix (n x n), k > 0', function () { + + var m = CcsMatrix.diagonal([3, 3], 1, 1); + + assert.deepEqual(m._size, [3, 3]); + assert.deepEqual(m._values, [1, 1]); + assert.deepEqual(m._index, [0, 1]); + assert.deepEqual(m._ptr, [0, 0, 1, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 1, 0], + [0, 0, 1], + [0, 0, 0] + ]); + }); + + it('should create CCS matrix (n x n), k < 0', function () { + + var m = CcsMatrix.diagonal([3, 3], 1, -1); + + assert.deepEqual(m._size, [3, 3]); + assert.deepEqual(m._values, [1, 1]); + assert.deepEqual(m._index, [1, 2]); + assert.deepEqual(m._ptr, [0, 1, 2, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 0, 0], + [1, 0, 0], + [0, 1, 0] + ]); + }); + + it('should create CCS matrix (n x n), vector value', function () { + + var m = CcsMatrix.diagonal([3, 3], [1, 2, 3]); + + assert.deepEqual(m._size, [3, 3]); + assert.deepEqual(m._values, [1, 2, 3]); + assert.deepEqual(m._index, [0, 1, 2]); + assert.deepEqual(m._ptr, [0, 1, 2, 3]); + + assert.deepEqual( + m.toArray(), + [ + [1, 0, 0], + [0, 2, 0], + [0, 0, 3] + ]); + }); + + it('should create CCS matrix (n x n), vector value, k > 0', function () { + + var m = CcsMatrix.diagonal([3, 3], [1, 2], 1); + + assert.deepEqual(m._size, [3, 3]); + assert.deepEqual(m._values, [1, 2]); + assert.deepEqual(m._index, [0, 1]); + assert.deepEqual(m._ptr, [0, 0, 1, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 1, 0], + [0, 0, 2], + [0, 0, 0] + ]); + }); + + it('should create CCS matrix (n x n), vector value, k < 0', function () { + + var m = CcsMatrix.diagonal([3, 3], [1, 2], -1); + + assert.deepEqual(m._size, [3, 3]); + assert.deepEqual(m._values, [1, 2]); + assert.deepEqual(m._index, [1, 2]); + assert.deepEqual(m._ptr, [0, 1, 2, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 0, 0], + [1, 0, 0], + [0, 2, 0] + ]); + }); + it('should create CCS matrix (n x n), complex number', function () { var m = CcsMatrix.diagonal([3, 3], new Complex(1, 1)); @@ -1253,6 +1343,101 @@ describe('CcsMatrix', function() { ]); }); + it('should create CCS matrix (m x n), m > n, k > 0', function () { + + var m = CcsMatrix.diagonal([4, 3], 1, 1); + + assert.deepEqual(m._size, [4, 3]); + assert.deepEqual(m._values, [1, 1]); + assert.deepEqual(m._index, [0, 1]); + assert.deepEqual(m._ptr, [0, 0, 1, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 1, 0], + [0, 0, 1], + [0, 0, 0], + [0, 0, 0] + ]); + }); + + it('should create CCS matrix (m x n), m > n, k < 0', function () { + + var m = CcsMatrix.diagonal([4, 3], 1, -1); + + assert.deepEqual(m._size, [4, 3]); + assert.deepEqual(m._values, [1, 1, 1]); + assert.deepEqual(m._index, [1, 2, 3]); + assert.deepEqual(m._ptr, [0, 1, 2, 3]); + + assert.deepEqual( + m.toArray(), + [ + [0, 0, 0], + [1, 0, 0], + [0, 1, 0], + [0, 0, 1], + ]); + }); + + it('should create CCS matrix (m x n), m > n, vector value', function () { + + var m = CcsMatrix.diagonal([4, 3], [1, 2, 3]); + + assert.deepEqual(m._size, [4, 3]); + assert.deepEqual(m._values, [1, 2, 3]); + assert.deepEqual(m._index, [0, 1, 2]); + assert.deepEqual(m._ptr, [0, 1, 2, 3]); + + assert.deepEqual( + m.toArray(), + [ + [1, 0, 0], + [0, 2, 0], + [0, 0, 3], + [0, 0, 0] + ]); + }); + + it('should create CCS matrix (m x n), m > n, vector value, k > 0', function () { + + var m = CcsMatrix.diagonal([4, 3], [1, 2], 1); + + assert.deepEqual(m._size, [4, 3]); + assert.deepEqual(m._values, [1, 2]); + assert.deepEqual(m._index, [0, 1]); + assert.deepEqual(m._ptr, [0, 0, 1, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 1, 0], + [0, 0, 2], + [0, 0, 0], + [0, 0, 0] + ]); + }); + + it('should create CCS matrix (m x n), m > n, vector value, k < 0', function () { + + var m = CcsMatrix.diagonal([4, 3], [1, 2, 3], -1); + + assert.deepEqual(m._size, [4, 3]); + assert.deepEqual(m._values, [1, 2, 3]); + assert.deepEqual(m._index, [1, 2, 3]); + assert.deepEqual(m._ptr, [0, 1, 2, 3]); + + assert.deepEqual( + m.toArray(), + [ + [0, 0, 0], + [1, 0, 0], + [0, 2, 0], + [0, 0, 3] + ]); + }); + it('should create CCS matrix (m x n), m < n', function () { var m = CcsMatrix.diagonal([3, 4], 1); @@ -1270,6 +1455,96 @@ describe('CcsMatrix', function() { [0, 0, 1, 0] ]); }); + + it('should create CCS matrix (m x n), m < n, k > 0', function () { + + var m = CcsMatrix.diagonal([3, 4], 1, 1); + + assert.deepEqual(m._size, [3, 4]); + assert.deepEqual(m._values, [1, 1, 1]); + assert.deepEqual(m._index, [0, 1, 2]); + assert.deepEqual(m._ptr, [0, 0, 1, 2, 3]); + + assert.deepEqual( + m.toArray(), + [ + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1] + ]); + }); + + it('should create CCS matrix (m x n), m < n, k < 0', function () { + + var m = CcsMatrix.diagonal([3, 4], 1, -1); + + assert.deepEqual(m._size, [3, 4]); + assert.deepEqual(m._values, [1, 1]); + assert.deepEqual(m._index, [1, 2]); + assert.deepEqual(m._ptr, [0, 1, 2, 2, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 0, 0, 0], + [1, 0, 0, 0], + [0, 1, 0, 0] + ]); + }); + + it('should create CCS matrix (m x n), m < n, vector value', function () { + + var m = CcsMatrix.diagonal([3, 4], [1, 2, 3]); + + assert.deepEqual(m._size, [3, 4]); + assert.deepEqual(m._values, [1, 2, 3]); + assert.deepEqual(m._index, [0, 1, 2]); + assert.deepEqual(m._ptr, [0, 1, 2, 3, 3]); + + assert.deepEqual( + m.toArray(), + [ + [1, 0, 0, 0], + [0, 2, 0, 0], + [0, 0, 3, 0] + ]); + }); + + it('should create CCS matrix (m x n), m < n, vector value, k > 0', function () { + + var m = CcsMatrix.diagonal([3, 4], [1, 2, 3], 1); + + assert.deepEqual(m._size, [3, 4]); + assert.deepEqual(m._values, [1, 2, 3]); + assert.deepEqual(m._index, [0, 1, 2]); + assert.deepEqual(m._ptr, [0, 0, 1, 2, 3]); + + assert.deepEqual( + m.toArray(), + [ + [0, 1, 0, 0], + [0, 0, 2, 0], + [0, 0, 0, 3] + ]); + }); + + it('should create CCS matrix (m x n), m < n, vector value, k < 0', function () { + + var m = CcsMatrix.diagonal([3, 4], [1, 2], -1); + + assert.deepEqual(m._size, [3, 4]); + assert.deepEqual(m._values, [1, 2]); + assert.deepEqual(m._index, [1, 2]); + assert.deepEqual(m._ptr, [0, 1, 2, 2, 2]); + + assert.deepEqual( + m.toArray(), + [ + [0, 0, 0, 0], + [1, 0, 0, 0], + [0, 2, 0, 0] + ]); + }); }); describe('transpose', function () {