mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-18 14:59:29 +00:00
CCS and Dense matrix updates
This commit is contained in:
parent
a072041fac
commit
9e214d030d
@ -6,6 +6,7 @@ var DimensionError = require('../../error/DimensionError');
|
||||
var array = util.array;
|
||||
var object = util.object;
|
||||
var string = util.string;
|
||||
var number = util.number;
|
||||
|
||||
var isArray = Array.isArray;
|
||||
var validateIndex = array.validateIndex;
|
||||
@ -47,21 +48,36 @@ module.exports = function (math) {
|
||||
for (var i = 0; i < rows; i++) {
|
||||
// current row
|
||||
var row = data[i];
|
||||
// update columns
|
||||
if (j === 0 && columns < row.length)
|
||||
columns = row.length;
|
||||
// check row has column
|
||||
if (j < row.length) {
|
||||
// value
|
||||
var v = row[j];
|
||||
// check value != 0
|
||||
if (!math.equal(v, 0)) {
|
||||
// check row is an array
|
||||
if (isArray(row)) {
|
||||
// update columns if needed (only on first column)
|
||||
if (j ===0 && columns < row.length)
|
||||
columns = row.length;
|
||||
// check row has column
|
||||
if (j < row.length) {
|
||||
// value
|
||||
var v = row[j];
|
||||
// check value != 0
|
||||
if (!math.equal(v, 0)) {
|
||||
// store value
|
||||
this._values.push(v);
|
||||
// index
|
||||
this._index.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// update columns if needed (only on first column)
|
||||
if (j === 0 && columns < 1)
|
||||
columns = 1;
|
||||
// check value != 0 (row is a scalar)
|
||||
if (!math.equal(row, 0)) {
|
||||
// store value
|
||||
this._values.push(v);
|
||||
this._values.push(row);
|
||||
// index
|
||||
this._index.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// increment index
|
||||
j++;
|
||||
@ -286,7 +302,7 @@ module.exports = function (math) {
|
||||
* var value = matrix.subset(index, replacement) // replace subset
|
||||
*
|
||||
* @param {Index} index
|
||||
* @param {Array | DenseFormat | *} [replacement]
|
||||
* @param {Array | CcsFormat | *} [replacement]
|
||||
* @param {*} [defaultValue=0] Default value, filled in on new entries when
|
||||
* the matrix is resized. If not provided,
|
||||
* new matrix elements will be filled with zeros.
|
||||
@ -304,9 +320,9 @@ module.exports = function (math) {
|
||||
* each entry of the matrix.
|
||||
* @param {function} callback The callback function is invoked with three
|
||||
* parameters: the value of the element, the index
|
||||
* of the element, and the DenseFormat being traversed.
|
||||
* of the element, and the Matrix being traversed.
|
||||
* @param {Matrix} matrix The Matrix instance
|
||||
* @return {DenseFormat} matrix
|
||||
* @return {CcsFormat} matrix
|
||||
*/
|
||||
CcsFormat.prototype.map = function (callback, matrix) {
|
||||
// result arrays
|
||||
@ -327,11 +343,13 @@ module.exports = function (math) {
|
||||
// store value
|
||||
values.push(v);
|
||||
// index
|
||||
index.push(i);
|
||||
index.push(x);
|
||||
}
|
||||
};
|
||||
// loop columns
|
||||
for (var j = 0; j < columns; j++) {
|
||||
// store pointer to values index
|
||||
ptr.push(values.length);
|
||||
// k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
|
||||
var k0 = this._ptr[j];
|
||||
var k1 = this._ptr[j + 1];
|
||||
@ -349,7 +367,7 @@ module.exports = function (math) {
|
||||
// increment k
|
||||
k++;
|
||||
// update pointer
|
||||
p = j + 1;
|
||||
p = i + 1;
|
||||
}
|
||||
// zero values
|
||||
for (var y = p; y < rows; y++)
|
||||
@ -366,6 +384,178 @@ module.exports = function (math) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute a callback function on each entry of the matrix.
|
||||
* @param {function} callback The callback function is invoked with three
|
||||
* parameters: the value of the element, the index
|
||||
* of the element, and the Matrix being traversed.
|
||||
* @param {Matrix} matrix The Matrix instance
|
||||
*/
|
||||
CcsFormat.prototype.forEach = function (callback, matrix) {
|
||||
// values index
|
||||
var k = 0;
|
||||
// rows and columns
|
||||
var rows = this._size[0];
|
||||
var columns = this._size[1];
|
||||
// loop columns
|
||||
for (var j = 0; j < columns; j++) {
|
||||
// k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
|
||||
var k0 = this._ptr[j];
|
||||
var k1 = this._ptr[j + 1];
|
||||
// column pointer
|
||||
var p = 0;
|
||||
// check k is within [k0, k1[
|
||||
while (k >= k0 && k < k1) {
|
||||
// row index
|
||||
var i = this._index[k];
|
||||
// zero values
|
||||
for (var x = p; x < i; x++)
|
||||
callback(0, [x, j], matrix);
|
||||
// value @ k
|
||||
callback(this._values[k], [i, j], matrix);
|
||||
// increment k
|
||||
k++;
|
||||
// update pointer
|
||||
p = i + 1;
|
||||
}
|
||||
// zero values
|
||||
for (var y = p; y < rows; y++)
|
||||
callback(0, [y, j], matrix);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize the matrix
|
||||
* @param {Number[]} size
|
||||
* @param {*} [defaultValue=0] Default value, filled in on new entries.
|
||||
* If not provided, the matrix elements will
|
||||
* be filled with zeros.
|
||||
* @return {CcsFormat} self The matrix itself is returned
|
||||
*/
|
||||
CcsFormat.prototype.resize = function (size, defaultValue) {
|
||||
// validate arguments
|
||||
if (!isArray(size))
|
||||
throw new TypeError('Array expected');
|
||||
if (size.length !== 2)
|
||||
throw new Error('Only two dimensions matrix are supported');
|
||||
|
||||
// check sizes
|
||||
size.forEach(function (value) {
|
||||
if (!number.isNumber(value) || !number.isInteger(value) || value < 0) {
|
||||
throw new TypeError('Invalid size, must contain positive integers ' +
|
||||
'(size: ' + string.format(size) + ')');
|
||||
}
|
||||
});
|
||||
|
||||
// value to inser at the time of growing matrix
|
||||
var value = (defaultValue !== undefined) ? defaultValue : 0;
|
||||
// should we insert the value?
|
||||
var ins = !math.equal(value, 0);
|
||||
|
||||
// old columns and rows
|
||||
var r = this._size[0];
|
||||
var c = this._size[1];
|
||||
|
||||
// rows & columns
|
||||
var rows = size[0];
|
||||
var columns = size[1];
|
||||
|
||||
var i, j, k;
|
||||
|
||||
// check we need to increase columns
|
||||
if (columns > c) {
|
||||
// loop new columns
|
||||
for (j = c; j < columns; j++) {
|
||||
// update ptr for current column
|
||||
this._ptr[j] = this._values.length;
|
||||
// check we need to insert values
|
||||
if (ins) {
|
||||
// loop rows
|
||||
for (i = 0; i < r; i++) {
|
||||
// add new values
|
||||
this._values.push(value);
|
||||
// update index
|
||||
this._index.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
// store number of values in ptr
|
||||
this._ptr[columns] = this._values.length;
|
||||
}
|
||||
else if (columns < c) {
|
||||
// truncate ptr
|
||||
this._ptr.splice(columns + 1, c - columns);
|
||||
// truncate values and index
|
||||
this._values.splice(this._ptr[columns], this._values.length);
|
||||
this._index.splice(this._ptr[columns], this._index.length);
|
||||
}
|
||||
// update columns
|
||||
c = columns;
|
||||
|
||||
// check we need to increase rows
|
||||
if (rows > r) {
|
||||
// check we have to insert values
|
||||
if (ins) {
|
||||
// inserts
|
||||
var n = 0;
|
||||
// loop columns
|
||||
for (j = 0; j < c; j++) {
|
||||
// update ptr for current column
|
||||
this._ptr[j] = this._ptr[j] + n;
|
||||
// where to insert values
|
||||
k = this._ptr[j + 1] + n;
|
||||
// pointer
|
||||
var p = 0;
|
||||
// loop new rows, initialize pointer
|
||||
for (i = r; i < rows; i++, p++) {
|
||||
// add value
|
||||
this._values.splice(k + p, 0, value);
|
||||
// update index
|
||||
this._index.splice(k + p, 0, i);
|
||||
// increment inserts
|
||||
n++;
|
||||
}
|
||||
}
|
||||
// store number of values in ptr
|
||||
this._ptr[c] = this._values.length;
|
||||
}
|
||||
}
|
||||
else if (rows < r) {
|
||||
// deletes
|
||||
var d = 0;
|
||||
// loop columns
|
||||
for (j = 0; j < c; j++) {
|
||||
// update ptr for current column
|
||||
this._ptr[j] = this._ptr[j] - d;
|
||||
// where values start for next column
|
||||
var k0 = this._ptr[j];
|
||||
var k1 = this._ptr[j + 1] - d;
|
||||
// loop index
|
||||
for (k = k0; k < k1; k++) {
|
||||
// row
|
||||
i = this._index[k];
|
||||
// check we need to delete value and index
|
||||
if (i > rows - 1) {
|
||||
// remove value
|
||||
this._values.splice(k, 1);
|
||||
// remove item from index
|
||||
this._index.splice(k, 1);
|
||||
// increase deletes
|
||||
d++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// update ptr for current column
|
||||
this._ptr[j] = this._values.length;
|
||||
}
|
||||
|
||||
// update size
|
||||
this._size = [rows, columns];
|
||||
|
||||
// return the matrix itself
|
||||
return this;
|
||||
};
|
||||
|
||||
CcsFormat.diagonal = function (rows, columns, value) {
|
||||
// create arrays
|
||||
var values = [];
|
||||
|
||||
@ -416,7 +416,7 @@ module.exports = function (math) {
|
||||
* each entry of the matrix.
|
||||
* @param {function} callback The callback function is invoked with three
|
||||
* parameters: the value of the element, the index
|
||||
* of the element, and the DenseFormat being traversed.
|
||||
* of the element, and the Matrix being traversed.
|
||||
* @param {Matrix} matrix The Matrix instance
|
||||
* @return {DenseFormat} matrix
|
||||
*/
|
||||
@ -442,7 +442,7 @@ module.exports = function (math) {
|
||||
* Execute a callback function on each entry of the matrix.
|
||||
* @param {function} callback The callback function is invoked with three
|
||||
* parameters: the value of the element, the index
|
||||
* of the element, and the DenseFormat being traversed.
|
||||
* of the element, and the Matrix being traversed.
|
||||
* @param {Matrix} matrix The Matrix instance
|
||||
*/
|
||||
DenseFormat.prototype.forEach = function (callback, matrix) {
|
||||
|
||||
@ -255,7 +255,7 @@ describe('matrix', function() {
|
||||
it('should set a value in a matrix', function() {
|
||||
var m = new Matrix([[0, 0], [0, 0]]);
|
||||
|
||||
m.set([1,0], 5);
|
||||
m.set([1, 0], 5);
|
||||
assert.deepEqual(m, new Matrix([
|
||||
[0, 0],
|
||||
[5, 0]
|
||||
@ -512,26 +512,18 @@ describe('matrix', function() {
|
||||
var m, m2;
|
||||
|
||||
m = new Matrix([
|
||||
[[1,2],[3,4]],
|
||||
[[5,6],[7,8]],
|
||||
[[9,10],[11,12]],
|
||||
[[13,14],[15,16]]
|
||||
[1, 2, 3, 4],
|
||||
[5, 6, 7, 8],
|
||||
[9, 10, 11,12],
|
||||
[13, 14, 15,16]
|
||||
]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.valueOf(), [
|
||||
[[2,4],[6,8]],
|
||||
[[10,12],[14,16]],
|
||||
[[18,20],[22,24]],
|
||||
[[26,28],[30,32]]
|
||||
assert.deepEqual(m2.toArray(), [
|
||||
[2, 4, 6, 8],
|
||||
[10, 12, 14, 16],
|
||||
[18, 20, 22, 24],
|
||||
[26, 28, 30, 32]
|
||||
]);
|
||||
|
||||
m = new Matrix([1]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.valueOf(), [2]);
|
||||
|
||||
m = new Matrix([1,2,3]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.valueOf(), [2,4,6]);
|
||||
});
|
||||
|
||||
it('should work on empty matrices', function() {
|
||||
@ -541,43 +533,38 @@ describe('matrix', function() {
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new Matrix([[1,2,3], [4,5,6]]);
|
||||
var m = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
||||
|
||||
var m2 = m.map(
|
||||
function (value, index, obj) {
|
||||
return value + index[0] * 100 + index[1] * 10 + (obj === m ? 1000 : 0);
|
||||
}
|
||||
);
|
||||
|
||||
var m2 = m.map(function (value, index, obj) {
|
||||
return math.clone([value, index, obj === m]);
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
m2.toArray(),
|
||||
[
|
||||
[
|
||||
[1, [0, 0], true ],
|
||||
[2, [0, 1], true ],
|
||||
[3, [0, 2], true ]
|
||||
],
|
||||
[
|
||||
[4, [1, 0], true ],
|
||||
[5, [1, 1], true ],
|
||||
[6, [1, 2], true ]
|
||||
]
|
||||
[1001, 1012, 1023],
|
||||
[1104, 1115, 1126]
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('forEach', function() {
|
||||
|
||||
it('should run on all elements of the matrix, last dimension first', function() {
|
||||
it('should run on all elements of the matrix', function() {
|
||||
var m, output;
|
||||
|
||||
m = new Matrix([
|
||||
[[1,2],[3,4]],
|
||||
[[5,6],[7,8]],
|
||||
[[9,10],[11,12]],
|
||||
[[13,14],[15,16]]
|
||||
[1, 2, 3, 4],
|
||||
[5, 6, 7, 8],
|
||||
[9, 10, 11, 12],
|
||||
[13, 14, 15, 16]
|
||||
]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
|
||||
// assert all values were visited, order is Matrix storage format specific
|
||||
assert.deepEqual(output.sort(), [1, 10, 11,12, 13, 14, 15, 16, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
|
||||
m = new Matrix([1]);
|
||||
output = [];
|
||||
@ -587,7 +574,8 @@ describe('matrix', function() {
|
||||
m = new Matrix([1,2,3]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1,2,3]);
|
||||
// assert all values were visited, order is Matrix storage format specific
|
||||
assert.deepEqual(output.sort(), [1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should work on empty matrices', function() {
|
||||
@ -598,22 +586,21 @@ describe('matrix', function() {
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new Matrix([[1,2,3], [4,5,6]]);
|
||||
|
||||
var m = new Matrix(
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
]);
|
||||
var o = {};
|
||||
var output = [];
|
||||
m.forEach(function (value, index, obj) {
|
||||
output.push(math.clone([value, index, obj === m]));
|
||||
});
|
||||
assert.deepEqual(output, [
|
||||
[1, [0, 0], true ],
|
||||
[2, [0, 1], true ],
|
||||
[3, [0, 2], true ],
|
||||
[4, [1, 0], true ],
|
||||
[5, [1, 1], true ],
|
||||
[6, [1, 2], true ]
|
||||
]);
|
||||
m.forEach(
|
||||
function (value, index, obj) {
|
||||
output.push(value + index[0] * 100 + index[1] * 10 + (obj === m ? 1000 : 0));
|
||||
}
|
||||
);
|
||||
// assert all values were visited, order is Matrix storage format specific
|
||||
assert.deepEqual(output.sort(), [1001, 1012, 1023, 1104, 1115, 1126]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('clone', function() {
|
||||
|
||||
@ -64,6 +64,15 @@ describe('CcsFormat', function() {
|
||||
assert.deepEqual(m._ptr, [0]);
|
||||
});
|
||||
|
||||
it('should create a CCS from a vector', function () {
|
||||
var m = new CcsFormat([1, 2, 3]);
|
||||
assert.equal(m._format, 'ccs');
|
||||
assert.deepEqual(m._size, [3, 1]);
|
||||
assert.deepEqual(m._values, [1, 2, 3]);
|
||||
assert.deepEqual(m._index, [0, 1, 2]);
|
||||
assert.deepEqual(m._ptr, [0, 3]);
|
||||
});
|
||||
|
||||
it('should throw an error when called without new keyword', function () {
|
||||
assert.throws(function () { CcsFormat(); }, /Constructor must be called with the new operator/);
|
||||
});
|
||||
@ -341,6 +350,212 @@ describe('CcsFormat', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('resize', function() {
|
||||
|
||||
it('should increase columns as needed, zero value', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
]);
|
||||
m.resize([2, 4]);
|
||||
assert.deepEqual(m._size, [2, 4]);
|
||||
assert.deepEqual(m._values, [1, 4, 2, 5, 3, 6]);
|
||||
assert.deepEqual(m._index, [0, 1, 0, 1, 0, 1]);
|
||||
assert.deepEqual(m._ptr, [0, 2, 4, 6, 6]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[1, 2, 3, 0],
|
||||
[4, 5, 6, 0]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should increase columns as needed, non zero value', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
]);
|
||||
m.resize([2, 4], 100);
|
||||
assert.deepEqual(m._size, [2, 4]);
|
||||
assert.deepEqual(m._values, [1, 4, 2, 5, 3, 6, 100, 100]);
|
||||
assert.deepEqual(m._index, [0, 1, 0, 1, 0, 1, 0, 1]);
|
||||
assert.deepEqual(m._ptr, [0, 2, 4, 6, 8]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[1, 2, 3, 100],
|
||||
[4, 5, 6, 100]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should increase rows as needed, zero value', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
]);
|
||||
m.resize([3, 3]);
|
||||
assert.deepEqual(m._size, [3, 3]);
|
||||
assert.deepEqual(m._values, [1, 4, 2, 5, 3, 6]);
|
||||
assert.deepEqual(m._index, [0, 1, 0, 1, 0, 1]);
|
||||
assert.deepEqual(m._ptr, [0, 2, 4, 6]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[0, 0, 0]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should increase rows as needed, non zero value', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
]);
|
||||
m.resize([3, 3], 100);
|
||||
assert.deepEqual(m._size, [3, 3]);
|
||||
assert.deepEqual(m._values, [1, 4, 100, 2, 5, 100, 3, 6, 100]);
|
||||
assert.deepEqual(m._index, [0, 1, 2, 0, 1, 2, 0, 1, 2]);
|
||||
assert.deepEqual(m._ptr, [0, 3, 6, 9]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[100, 100, 100]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should increase rows & columns as needed, zero value, empty CCS', function() {
|
||||
var m = new CcsFormat([]);
|
||||
m.resize([2, 2]);
|
||||
assert.deepEqual(m._size, [2, 2]);
|
||||
assert.deepEqual(m._values, []);
|
||||
assert.deepEqual(m._index, []);
|
||||
assert.deepEqual(m._ptr, [0, 0, 0]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[0, 0],
|
||||
[0, 0]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should increase rows & columns as needed, non zero value, empty CCS', function() {
|
||||
var m = new CcsFormat([]);
|
||||
m.resize([2, 2], 100);
|
||||
assert.deepEqual(m._size, [2, 2]);
|
||||
assert.deepEqual(m._values, [100, 100, 100, 100]);
|
||||
assert.deepEqual(m._index, [0, 1, 0, 1]);
|
||||
assert.deepEqual(m._ptr, [0, 2, 4]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[100, 100],
|
||||
[100, 100]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should decrease columns as needed', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
]);
|
||||
m.resize([2, 2]);
|
||||
assert.deepEqual(m._size, [2, 2]);
|
||||
assert.deepEqual(m._values, [1, 4, 2, 5]);
|
||||
assert.deepEqual(m._index, [0, 1, 0, 1]);
|
||||
assert.deepEqual(m._ptr, [0, 2, 4]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[1, 2],
|
||||
[4, 5]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should decrease columns as needed, zero matrix', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]
|
||||
]);
|
||||
m.resize([2, 2]);
|
||||
assert.deepEqual(m._size, [2, 2]);
|
||||
assert.deepEqual(m._values, []);
|
||||
assert.deepEqual(m._index, []);
|
||||
assert.deepEqual(m._ptr, [0, 0, 0]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[0, 0],
|
||||
[0, 0]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should decrease rows as needed', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]);
|
||||
m.resize([1, 2]);
|
||||
assert.deepEqual(m._size, [1, 2]);
|
||||
assert.deepEqual(m._values, [1, 2]);
|
||||
assert.deepEqual(m._index, [0, 0]);
|
||||
assert.deepEqual(m._ptr, [0, 1, 2]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[1, 2]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should decrease rows as needed, zero CCS', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[0, 0],
|
||||
[0, 0]
|
||||
]);
|
||||
m.resize([1, 2]);
|
||||
assert.deepEqual(m._size, [1, 2]);
|
||||
assert.deepEqual(m._values, []);
|
||||
assert.deepEqual(m._index, []);
|
||||
assert.deepEqual(m._ptr, [0, 0, 0]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[0, 0]
|
||||
]);
|
||||
});
|
||||
|
||||
it('should decrease rows & columns as needed, zero CCS', function() {
|
||||
var m = new CcsFormat(
|
||||
[
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0]
|
||||
]);
|
||||
m.resize([2, 2]);
|
||||
assert.deepEqual(m._size, [2, 2]);
|
||||
assert.deepEqual(m._values, []);
|
||||
assert.deepEqual(m._index, []);
|
||||
assert.deepEqual(m._ptr, [0, 0, 0]);
|
||||
assert.deepEqual(
|
||||
m.toArray(),
|
||||
[
|
||||
[0, 0],
|
||||
[0, 0]
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('clone', function() {
|
||||
|
||||
it('should clone the matrix properly', function() {
|
||||
@ -356,6 +571,107 @@ describe('CcsFormat', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('map', function() {
|
||||
|
||||
it('should apply the given function to all elements in the matrix', function() {
|
||||
var m, m2;
|
||||
|
||||
m = new CcsFormat([
|
||||
[1, 2, 3, 4],
|
||||
[5, 6, 7, 8],
|
||||
[9, 10, 11,12],
|
||||
[13, 14, 15,16]
|
||||
]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.toArray(), [
|
||||
[2, 4, 6, 8],
|
||||
[10, 12, 14, 16],
|
||||
[18, 20, 22, 24],
|
||||
[26, 28, 30, 32]
|
||||
]);
|
||||
|
||||
m = new CcsFormat([1]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.toArray(), [[2]]);
|
||||
|
||||
m = new CcsFormat([1,2,3]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.toArray(), [[2],[4],[6]]);
|
||||
});
|
||||
|
||||
it('should work on empty matrices', function() {
|
||||
var m = new CcsFormat([]);
|
||||
var m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.toArray(), []);
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new CcsFormat([[1, 2, 3], [4, 5, 6]]);
|
||||
var o = {};
|
||||
|
||||
var m2 = m.map(
|
||||
function (value, index, obj) {
|
||||
return value + index[0] * 100 + index[1] * 10 + (obj === o ? 1000 : 0);
|
||||
},
|
||||
o
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
m2.toArray(),
|
||||
[
|
||||
[1001, 1012, 1023],
|
||||
[1104, 1115, 1126]
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('forEach', function() {
|
||||
|
||||
it('should run on all elements of the matrix', function() {
|
||||
var m, output;
|
||||
|
||||
m = new CcsFormat([
|
||||
[1, 2, 3, 4],
|
||||
[5, 6, 7, 8],
|
||||
[9, 10, 11,12],
|
||||
[13, 14, 15,16]
|
||||
]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16]);
|
||||
|
||||
m = new CcsFormat([1]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1]);
|
||||
|
||||
m = new CcsFormat([1,2,3]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1,2,3]);
|
||||
});
|
||||
|
||||
it('should work on empty matrices', function() {
|
||||
m = new CcsFormat([]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, []);
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new CcsFormat([[1,2,3], [4,5,6]]);
|
||||
var o = {};
|
||||
var output = [];
|
||||
m.forEach(
|
||||
function (value, index, obj) {
|
||||
output.push(value + index[0] * 100 + index[1] * 10 + (obj === o ? 1000 : 0));
|
||||
},
|
||||
o
|
||||
);
|
||||
assert.deepEqual(output, [1001, 1104, 1012, 1115, 1023, 1126]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toString', function() {
|
||||
|
||||
it('should return string representation of matrix', function() {
|
||||
|
||||
@ -314,6 +314,121 @@ describe('DenseFormat', function() {
|
||||
assert.deepEqual(m1._data, m2._data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('map', function() {
|
||||
|
||||
it('should apply the given function to all elements in the matrix', function() {
|
||||
var m = new DenseFormat([
|
||||
[[1,2],[3,4]],
|
||||
[[5,6],[7,8]],
|
||||
[[9,10],[11,12]],
|
||||
[[13,14],[15,16]]
|
||||
]);
|
||||
var m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(
|
||||
m2.valueOf(),
|
||||
[
|
||||
[[2,4],[6,8]],
|
||||
[[10,12],[14,16]],
|
||||
[[18,20],[22,24]],
|
||||
[[26,28],[30,32]]
|
||||
]);
|
||||
|
||||
m = new DenseFormat([1]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.valueOf(), [2]);
|
||||
|
||||
m = new DenseFormat([1,2,3]);
|
||||
m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.valueOf(), [2,4,6]);
|
||||
});
|
||||
|
||||
it('should work on empty matrices', function() {
|
||||
var m = new DenseFormat([]);
|
||||
var m2 = m.map(function (value) { return value * 2; });
|
||||
assert.deepEqual(m2.toArray(), []);
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new DenseFormat([[1,2,3], [4,5,6]]);
|
||||
var o = {};
|
||||
var m2 = m.map(
|
||||
function (value, index, obj) {
|
||||
return math.clone([value, index, obj === o]);
|
||||
},
|
||||
o
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
m2.toArray(),
|
||||
[
|
||||
[
|
||||
[1, [0, 0], true ],
|
||||
[2, [0, 1], true ],
|
||||
[3, [0, 2], true ]
|
||||
],
|
||||
[
|
||||
[4, [1, 0], true ],
|
||||
[5, [1, 1], true ],
|
||||
[6, [1, 2], true ]
|
||||
]
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('forEach', function() {
|
||||
|
||||
it('should run on all elements of the matrix, last dimension first', function() {
|
||||
var m, output;
|
||||
|
||||
m = new DenseFormat([
|
||||
[[1,2],[3,4]],
|
||||
[[5,6],[7,8]],
|
||||
[[9,10],[11,12]],
|
||||
[[13,14],[15,16]]
|
||||
]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
|
||||
|
||||
m = new DenseFormat([1]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1]);
|
||||
|
||||
m = new DenseFormat([1,2,3]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, [1,2,3]);
|
||||
});
|
||||
|
||||
it('should work on empty matrices', function() {
|
||||
m = new DenseFormat([]);
|
||||
output = [];
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, []);
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new DenseFormat([[1,2,3], [4,5,6]]);
|
||||
var o = {};
|
||||
var output = [];
|
||||
m.forEach(
|
||||
function (value, index, obj) {
|
||||
output.push(math.clone([value, index, obj === o]));
|
||||
},
|
||||
o
|
||||
);
|
||||
assert.deepEqual(output, [
|
||||
[1, [0, 0], true ],
|
||||
[2, [0, 1], true ],
|
||||
[3, [0, 2], true ],
|
||||
[4, [1, 0], true ],
|
||||
[5, [1, 1], true ],
|
||||
[6, [1, 2], true ]
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toString', function() {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user