diff --git a/lib/function/construction/matrix.js b/lib/function/construction/matrix.js index 52000e0a2..a8f4a4360 100644 --- a/lib/function/construction/matrix.js +++ b/lib/function/construction/matrix.js @@ -2,37 +2,30 @@ var string = require('../../util/string'), + isArray = Array.isArray, isString = string.isString; module.exports = function (math) { var Matrix = math.type.Matrix; - var _createStorage = function (data, format) { + var _createMatrix = function (data, format) { // check data is an array - if (isArray(data)) { - // format to use - format = format || 'default'; - // check format - if (!isString(format)) - throw new TypeError('format must be a string value'); - // get format constructor - var f = Matrix.format[format]; - if (!f) - throw new SyntaxError('Unsupported Matrix Storage Format: ' + format); - // create instance - return new f(data); + if (!isArray(data) && !(data instanceof Matrix)) { + // throw + throw new TypeError('data must be an array value or Matrix instance'); } - // check it is a storage json representation - if (typeof data === 'object' && isString(data.format)) { - // get format constructor - var f = Matrix.format[data.format]; - if (!f) - throw new SyntaxError('Unsupported Matrix Storage Format: ' + data.format); - // deserialize json - return f.fromJSON(data); - } - throw new SyntaxError('Unsupported data structure'); + // check format is a string + if (!isString(format)) { + // throw + throw new TypeError('format must be a string value'); + } + // get format constructor + var F = Matrix.format[format]; + if (!F) + throw new SyntaxError('Unsupported Matrix Storage Format: ' + format); + // create instance + return new F(data); }; /** @@ -64,19 +57,32 @@ module.exports = function (math) { * @return {Matrix} The created matrix */ math.matrix = function matrix(data, format) { - if (arguments.length > 2) { - throw new math.error.ArgumentsError('matrix', arguments.length, 0, 2); + // check arguments + switch (arguments.length) { + case 0: + // set data and format + data = []; + format = 'default'; + break; + case 1: + // check data was provided + if (isArray(data) || data instanceof Matrix) { + // use default format + format = 'default'; + } + else if (isString(data)) { + // set format + format = data; + // empty array + data = []; + } + break; + case 2: + break; + default: + throw new math.error.ArgumentsError('matrix', arguments.length, 0, 2); } - // format to use - format = format || 'default'; - // check format - if (!isString(format)) - throw new TypeError('format must be a string value'); - // get format constructor - var f = Matrix.format[format]; - if (!f) - throw new SyntaxError('Unsupported Matrix Storage Format: ' + format); - // create instance - return new f(data); + // create matrix + return _createMatrix(data, format); }; }; diff --git a/lib/function/matrix/ones.js b/lib/function/matrix/ones.js index c88b2e432..5aefe32f2 100644 --- a/lib/function/matrix/ones.js +++ b/lib/function/matrix/ones.js @@ -42,7 +42,7 @@ module.exports = function (math, config) { var asMatrix = (size instanceof Matrix) ? true : (isArray(size) ? false : (config.matrix === 'matrix')); - if (args.length == 0) { + if (args.length === 0) { // output an empty matrix return asMatrix ? math.matrix() : []; } diff --git a/lib/function/matrix/zeros.js b/lib/function/matrix/zeros.js index d7c03410c..b1776fa14 100644 --- a/lib/function/matrix/zeros.js +++ b/lib/function/matrix/zeros.js @@ -8,6 +8,7 @@ module.exports = function (math, config) { collection = math.collection, array = util.array, + string = util.string, isArray = Array.isArray; /** @@ -34,37 +35,42 @@ module.exports = function (math, config) { * ones, eye, size, range * * @param {...Number | Array} size The size of each dimension of the matrix + * @param {string} [format] The Matrix storage format * @return {Array | Matrix | Number} A matrix filled with zeros */ math.zeros = function zeros (size) { + // args var args = collection.argsToArray(arguments); - var asMatrix = (size instanceof Matrix) ? true : - (isArray(size) ? false : (config.matrix === 'matrix')); - - if (args.length == 0) { + // check format was provided + var f = args.length > 0 && string.isString(args[args.length - 1]) ? args[args.length - 1] : undefined; + if (f) { + // remove last arg + args.splice(args.length - 1, 1); + } + + // check result type + var asMatrix = f || (size instanceof Matrix) ? true : (isArray(size) ? false : (config.matrix === 'matrix')); + + if (args.length === 0) { // output an empty matrix - return asMatrix ? math.matrix() : []; + return asMatrix ? (f ? math.matrix(f) : math.matrix()) : []; } - else { - // output an array or matrix + // convert arguments from bignumber to numbers if needed + var asBigNumber = false; + args = args.map(function (value) { + if (value instanceof BigNumber) { + asBigNumber = true; + return value.toNumber(); + } else { + return value; + } + }); - // convert arguments from bignumber to numbers if needed - var asBigNumber = false; - args = args.map(function (value) { - if (value instanceof BigNumber) { - asBigNumber = true; - return value.toNumber(); - } else { - return value; - } - }); + // resize the matrix + var res = []; + var defaultValue = asBigNumber ? new BigNumber(0) : 0; + res = array.resize(res, args, defaultValue); - // resize the matrix - var res = []; - var defaultValue = asBigNumber ? new BigNumber(0) : 0; - res = array.resize(res, args, defaultValue); - - return asMatrix ? math.matrix(res) : res; - } + return asMatrix ? (f ? math.matrix(res, f) : math.matrix(res)) : res; }; }; diff --git a/lib/type/collection.js b/lib/type/collection.js index 3ac572f7e..047f49549 100644 --- a/lib/type/collection.js +++ b/lib/type/collection.js @@ -26,7 +26,7 @@ module.exports = function (math) { * @returns {Array} array */ collection.argsToArray = function(args) { - if (args.length == 0) { + if (args.length === 0) { // fn() return []; } diff --git a/lib/type/matrix/CcsMatrix.js b/lib/type/matrix/CcsMatrix.js index 8e4cd9a0f..bf3f5a39f 100644 --- a/lib/type/matrix/CcsMatrix.js +++ b/lib/type/matrix/CcsMatrix.js @@ -34,7 +34,7 @@ module.exports = function (math) { _createFromArray(this, data.toArray()); } } - else if (data && isArray(data.values) && isArray(data.index) && isArray(data.ptr)) { + else if (data && isArray(data.values) && isArray(data.index) && isArray(data.ptr) && isArray(data.size)) { // initialize fields this._values = data.values; this._index = data.index; @@ -806,6 +806,27 @@ module.exports = function (math) { return new CcsMatrix(json); }; + /** + * Generate a matrix with zero values + * @param {Integer} rows The number of rows + * @param {Integer} columns The number of columns + * + * @returns {CcsMatrix} + */ + CcsMatrix.zeros = function (rows, columns) { + // create ptr + var ptr = []; + for (var j = 0; j <= columns; j++) + ptr[j] = 0; + // create matrix + return new CcsMatrix({ + values: [], + index: [], + ptr: ptr, + size: [rows, columns] + }); + }; + CcsMatrix.diagonal = function (rows, columns, value) { // create arrays var values = []; diff --git a/test/function/construction/matrix.test.js b/test/function/construction/matrix.test.js index 4d44730ec..ddf3f36dd 100644 --- a/test/function/construction/matrix.test.js +++ b/test/function/construction/matrix.test.js @@ -26,6 +26,13 @@ describe('matrix', function() { assert.deepEqual(c, matrix([[1,2],[3,4]], 'dense')); assert.deepEqual(math.size(c), matrix([2,2], 'dense')); }); + + it('should be the identity if called with a matrix, CCS format', function() { + var b = matrix([[1,2],[3,4]], 'ccs'); + var c = matrix(b, 'ccs'); + assert.ok(c._values != b._values); // data should be cloned + assert.deepEqual(c, matrix([[1,2],[3,4]], 'ccs')); + }); it('should create a matrix from a range correctly', function() { var d = matrix(math.range(1,6)); @@ -35,15 +42,15 @@ describe('matrix', function() { }); it('should throw an error if called with a single number', function() { - assert.throws(function () {matrix(123)}, TypeError); + assert.throws(function () { matrix(123); }, TypeError); }); it('should throw an error if called with a unit', function() { - assert.throws(function () {matrix(math.unit('5cm'))}, TypeError); + assert.throws(function () { matrix(math.unit('5cm')); }, TypeError); }); it('should throw an error if called with 3 numbers', function() { - assert.throws(function () {matrix(2, 3, 4)}, error.ArgumentsError); + assert.throws(function () { matrix(2, 3, 4); }, error.ArgumentsError); }); it('should throw an error when called with an invalid storage format', function () { diff --git a/test/function/matrix/zeros.test.js b/test/function/matrix/zeros.test.js index 3c9433b22..42b6d0e4d 100644 --- a/test/function/matrix/zeros.test.js +++ b/test/function/matrix/zeros.test.js @@ -1,6 +1,5 @@ // test zeros var assert = require('assert'), - error = require('../../../lib/error/index'), math = require('../../../index'), zeros = math.zeros, matrix = math.matrix; @@ -12,7 +11,21 @@ describe('zeros', function() { assert.deepEqual(zeros([]), []); assert.deepEqual(zeros(matrix([])), matrix()); }); - + + /* + it('should create an empty matrix, CCS format', function () { + assert.deepEqual(zeros('ccs'), matrix('ccs')); + assert.deepEqual(zeros([], 'ccs'), matrix([], 'ccs')); + assert.deepEqual(zeros(matrix([]), 'ccs'), matrix('ccs')); + }); + + it('should create an empty matrix, CRS format', function () { + assert.deepEqual(zeros('crs'), matrix('crs')); + assert.deepEqual(zeros([], 'crs'), matrix([], 'crs')); + assert.deepEqual(zeros(matrix([]), 'crs'), matrix('crs')); + }); +*/ + it('should create a vector with zeros', function () { assert.deepEqual(zeros(3), matrix([0,0,0])); assert.deepEqual(zeros(matrix([4])), matrix([0,0,0,0])); diff --git a/test/type/matrix/CcsMatrix.test.js b/test/type/matrix/CcsMatrix.test.js index ea1867809..ec4a8a434 100644 --- a/test/type/matrix/CcsMatrix.test.js +++ b/test/type/matrix/CcsMatrix.test.js @@ -1244,4 +1244,30 @@ describe('CcsMatrix', function() { assert.throws(function () { m.transpose(); }); }); }); + + describe('zeros', function () { + + it('should generate a matrix with zeros', function() { + var m = CcsMatrix.zeros(2, 2); + assert.deepEqual( + m.toArray(), + [ + [0, 0], + [0, 0] + ]); + }); + + it('should generate a big matrix with zeros', function() { + var m = CcsMatrix.zeros(1000, 1000); + assert.deepEqual(m._values, []); + assert.deepEqual(m._index, []); + assert.equal(m._ptr.length, 1001); + assert.deepEqual(m._size, [1000, 1000]); + }); + + it('should throw an error for invalid matrix transpose', function() { + var m = new CcsMatrix([[]]); + assert.throws(function () { m.transpose(); }); + }); + }); }); \ No newline at end of file