mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
Getting or setting a subset of a matrix will automatically squeezed/unsqueezed the submatrix
This commit is contained in:
parent
f68bc8e5f2
commit
f48c07bdd8
@ -4,6 +4,10 @@ https://github.com/josdejong/mathjs
|
||||
|
||||
## not yet released, version 0.14.0
|
||||
|
||||
*WARNING: version 0.14 is incompatible with previous versions.*
|
||||
|
||||
- Getting a subset of a matrix will automatically squeeze the resulting subset,
|
||||
setting a subset of a matrix will automatically unsqueeze the given subset.
|
||||
- Removed concatenation of nested arrays in the expression parser.
|
||||
You can now input nested arrays like in JavaScript. Matrices can be
|
||||
concatenated using the function `concat`.
|
||||
|
||||
@ -41,8 +41,8 @@ parser = math.parser();
|
||||
|
||||
parser.eval('a = [1, 2; 3, 4]'); // Matrix, [[1, 2], [3, 4]]
|
||||
parser.eval('b = zeros(2, 2)'); // Matrix, [[0, 0], [0, 0]]
|
||||
parser.eval('b(1, 1:2) = [[5, 6]]'); // Matrix, [[5, 6], [0, 0]]
|
||||
parser.eval('b(2, :) = [[7, 8]]'); // Matrix, [[5, 6], [7, 8]]
|
||||
parser.eval('b(1, 1:2) = [5, 6]'); // Matrix, [[5, 6], [0, 0]]
|
||||
parser.eval('b(2, :) = [7, 8]'); // Matrix, [[5, 6], [7, 8]]
|
||||
parser.eval('c = a * b'); // Matrix, [[19, 22], [43, 50]]
|
||||
parser.eval('d = c(2, 1)'); // 43
|
||||
parser.eval('e = c(2, 1:end)'); // Matrix, [[43, 50]]
|
||||
|
||||
@ -135,8 +135,8 @@ print(parser.eval('f(2, 3)')); // 8
|
||||
console.log('\nmanipulate matrices');
|
||||
print(parser.eval('k = [1, 2; 3, 4]')); // [[1, 2], [3, 4]]
|
||||
print(parser.eval('l = zeros(2, 2)')); // [[0, 0], [0, 0]]
|
||||
print(parser.eval('l(1, 1:2) = [[5, 6]]')); // [[5, 6], [0, 0]]
|
||||
print(parser.eval('l(2, :) = [[7, 8]]')); // [[5, 6], [7, 8]]
|
||||
print(parser.eval('l(1, 1:2) = [5, 6]')); // [[5, 6], [0, 0]]
|
||||
print(parser.eval('l(2, :) = [7, 8]')); // [[5, 6], [7, 8]]
|
||||
print(parser.eval('m = k * l')); // [[19, 22], [43, 50]]
|
||||
print(parser.eval('n = m(2, 1)')); // 43
|
||||
print(parser.eval('n = m(:, 1)')); // [[19], [43]]
|
||||
|
||||
@ -16,7 +16,7 @@ module.exports = function (math) {
|
||||
BlockNode = require('../../expression/node/BlockNode.js'),
|
||||
ConstantNode = require('../../expression/node/ConstantNode.js'),
|
||||
FunctionNode = require('../../expression/node/FunctionNode.js'),
|
||||
MatrixNode = require('../../expression/node/MatrixNode.js'),
|
||||
ArrayNode = require('../../expression/node/ArrayNode.js'),
|
||||
OperatorNode = require('../../expression/node/OperatorNode.js'),
|
||||
ParamsNode = require('../../expression/node/ParamsNode.js'),
|
||||
RangeNode = require('../../expression/node/RangeNode.js'),
|
||||
@ -1042,7 +1042,7 @@ module.exports = function (math) {
|
||||
/**
|
||||
* parse the matrix
|
||||
* @param {Scope} scope
|
||||
* @return {Node} A MatrixNode
|
||||
* @return {Node} node
|
||||
* @private
|
||||
*/
|
||||
function parseMatrix (scope) {
|
||||
@ -1098,7 +1098,7 @@ module.exports = function (math) {
|
||||
}
|
||||
}
|
||||
|
||||
array = new MatrixNode(params);
|
||||
array = new ArrayNode(params);
|
||||
}
|
||||
else {
|
||||
// 1 dimensional vector
|
||||
@ -1113,7 +1113,7 @@ module.exports = function (math) {
|
||||
else {
|
||||
// this is an empty matrix "[ ]"
|
||||
getToken();
|
||||
array = new MatrixNode([]);
|
||||
array = new ArrayNode([]);
|
||||
}
|
||||
|
||||
// parse parameters
|
||||
@ -1128,7 +1128,7 @@ module.exports = function (math) {
|
||||
/**
|
||||
* Parse a single comma-separated row from a matrix, like 'a, b, c'
|
||||
* @param {Scope} scope
|
||||
* @return {MatrixNode} node
|
||||
* @return {ArrayNode} node
|
||||
*/
|
||||
function parseRow (scope) {
|
||||
var params = [parseAssignment(scope)];
|
||||
@ -1152,7 +1152,7 @@ module.exports = function (math) {
|
||||
}
|
||||
}
|
||||
|
||||
return new MatrixNode(params);
|
||||
return new ArrayNode(params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -299,10 +299,14 @@ function _set (matrix, index, submatrix) {
|
||||
submatrix = submatrix.valueOf();
|
||||
}
|
||||
|
||||
// calculate the size of the submatrix
|
||||
var subsize = array.size(submatrix);
|
||||
|
||||
if (isScalar) {
|
||||
// set a scalar
|
||||
// check whether submatrix is no matrix/array
|
||||
if (array.size(submatrix.valueOf()).length != 0) {
|
||||
|
||||
// check whether submatrix is a scalar
|
||||
if (subsize.length != 0) {
|
||||
throw new TypeError('Scalar value expected');
|
||||
}
|
||||
|
||||
@ -314,6 +318,12 @@ function _set (matrix, index, submatrix) {
|
||||
}
|
||||
else {
|
||||
// set a submatrix
|
||||
|
||||
// unsqueeze the submatrix when needed
|
||||
for (var i = 0, ii = size.length - subsize.length; i < ii; i++) {
|
||||
submatrix = [submatrix];
|
||||
}
|
||||
|
||||
var newSize = matrix._size.concat();
|
||||
_setSubmatrix (matrix._data, newSize, index, 0, submatrix);
|
||||
if (!object.deepEqual(matrix._size, newSize)) {
|
||||
|
||||
@ -172,12 +172,12 @@ describe('parse', function() {
|
||||
[7,8,9]
|
||||
])
|
||||
};
|
||||
assert.deepEqual(parseAndEval('a(2, :)', scope), new Matrix([[4,5,6]]));
|
||||
assert.deepEqual(parseAndEval('a(2, :2)', scope), new Matrix([[4,5]]));
|
||||
assert.deepEqual(parseAndEval('a(2, :end-1)', scope), new Matrix([[4,5]]));
|
||||
assert.deepEqual(parseAndEval('a(2, 2:)', scope), new Matrix([[5,6]]));
|
||||
assert.deepEqual(parseAndEval('a(2, 2:3)', scope), new Matrix([[5,6]]));
|
||||
assert.deepEqual(parseAndEval('a(2, 1:2:3)', scope), new Matrix([[4,6]]));
|
||||
assert.deepEqual(parseAndEval('a(2, :)', scope), new Matrix([4,5,6]));
|
||||
assert.deepEqual(parseAndEval('a(2, :2)', scope), new Matrix([4,5]));
|
||||
assert.deepEqual(parseAndEval('a(2, :end-1)', scope), new Matrix([4,5]));
|
||||
assert.deepEqual(parseAndEval('a(2, 2:)', scope), new Matrix([5,6]));
|
||||
assert.deepEqual(parseAndEval('a(2, 2:3)', scope), new Matrix([5,6]));
|
||||
assert.deepEqual(parseAndEval('a(2, 1:2:3)', scope), new Matrix([4,6]));
|
||||
assert.deepEqual(parseAndEval('a(:, 2)', scope), new Matrix([[2],[5],[8]]));
|
||||
assert.deepEqual(parseAndEval('a(:2, 2)', scope), new Matrix([[2],[5]]));
|
||||
assert.deepEqual(parseAndEval('a(:end-1, 2)', scope), new Matrix([[2],[5]]));
|
||||
@ -219,7 +219,7 @@ describe('parse', function() {
|
||||
assert.deepEqual(parseAndEval('a(1:3,1:2)', scope), new Matrix([[100,2],[3,10],[0,12]]));
|
||||
|
||||
scope.b = [[1,2],[3,4]];
|
||||
assert.deepEqual(parseAndEval('b(1,:)', scope), [[1, 2]]); // TODO: matrix should be squeezed
|
||||
assert.deepEqual(parseAndEval('b(1,:)', scope), [1, 2]);
|
||||
});
|
||||
|
||||
it('should get/set the matrix correctly for 3d matrices', function() {
|
||||
@ -249,10 +249,10 @@ describe('parse', function() {
|
||||
]
|
||||
]);
|
||||
assert.deepEqual(parseAndEval('size(f)', scope), new Matrix([2,2,2]));
|
||||
assert.deepEqual(parseAndEval('f(:,:,1)', scope), new Matrix([[[1],[2]],[[3],[4]]])); // TODO: last dimension should be squeezed
|
||||
assert.deepEqual(parseAndEval('f(:,:,2)', scope), new Matrix([[[5],[6]],[[7],[8]]])); // TODO: last dimension should be squeezed
|
||||
assert.deepEqual(parseAndEval('f(:,:,1)', scope), new Matrix([[[1],[2]],[[3],[4]]]));
|
||||
assert.deepEqual(parseAndEval('f(:,:,2)', scope), new Matrix([[[5],[6]],[[7],[8]]]));
|
||||
assert.deepEqual(parseAndEval('f(:,2,:)', scope), new Matrix([[[2,6]],[[4,8]]]));
|
||||
assert.deepEqual(parseAndEval('f(2,:,:)', scope), new Matrix([[[3,7],[4,8]]]));
|
||||
assert.deepEqual(parseAndEval('f(2,:,:)', scope), new Matrix([[3,7],[4,8]]));
|
||||
|
||||
parseAndEval('a=diag([1,2,3,4])', scope);
|
||||
assert.deepEqual(parseAndEval('a(3:end, 3:end)', scope), new Matrix([[3,0],[0,4]]));
|
||||
|
||||
@ -49,6 +49,8 @@ describe('subset', function() {
|
||||
var d = [[1,2], [3,4]];
|
||||
var g = matrix([[1,2], [3,4]]);
|
||||
|
||||
// TODO: test getting subset of an array and matrix
|
||||
|
||||
it('should set the right subset of an array', function() {
|
||||
assert.deepEqual(d, [[1,2], [3,4]]);
|
||||
assert.deepEqual(subset(d, index([0,2], 1), [[-2],[-4]]), [[1,-2], [3,-4]]);
|
||||
|
||||
@ -143,8 +143,8 @@ describe('matrix', function() {
|
||||
assert.deepEqual(m.size(), [3,3]);
|
||||
assert.deepEqual(m.subset(index(1,1)), 5);
|
||||
assert.deepEqual(m.subset(index([0,2],[0,2])).valueOf(), [[1,2],[4,5]]);
|
||||
assert.deepEqual(m.subset(index(1, [1,3])).valueOf(), [[5,6]]);
|
||||
assert.deepEqual(m.subset(index(0, [1,3])).valueOf(), [[2,3]]);
|
||||
assert.deepEqual(m.subset(index(1, [1,3])).valueOf(), [5,6]);
|
||||
assert.deepEqual(m.subset(index(0, [1,3])).valueOf(), [2,3]);
|
||||
assert.deepEqual(m.subset(index([1,3], 1)).valueOf(), [[5],[8]]);
|
||||
assert.deepEqual(m.subset(index([1,3], 2)).valueOf(), [[6],[9]]);
|
||||
|
||||
@ -154,8 +154,8 @@ describe('matrix', function() {
|
||||
assert.deepEqual(m.subset(index([0,2],[0,2],[0,2])).valueOf(), m.valueOf());
|
||||
assert.deepEqual(m.subset(index(0,0,0)), 1);
|
||||
assert.deepEqual(m.subset(index(1,1,1)).valueOf(), 8);
|
||||
assert.deepEqual(m.subset(index(1,1,[0,2])).valueOf(), [[[7,8]]]);
|
||||
assert.deepEqual(m.subset(index(1,[0,2],1)).valueOf(), [[[6],[8]]]);
|
||||
assert.deepEqual(m.subset(index(1,1,[0,2])).valueOf(), [7,8]);
|
||||
assert.deepEqual(m.subset(index(1,[0,2],1)).valueOf(), [[6],[8]]);
|
||||
});
|
||||
|
||||
it('should throw an error if the given subset is invalid', function() {
|
||||
@ -185,7 +185,9 @@ describe('matrix', function() {
|
||||
m.resize([3,3]);
|
||||
assert.deepEqual(m.valueOf(), [[0,0,0],[0,0,0],[0,0,0]]);
|
||||
m.subset(index([1,3], [1,3]), [[1,2],[3,4]]);
|
||||
assert.deepEqual(m.valueOf(), [[0,0,0],[0,1,2],[0,3,4]]);
|
||||
assert.deepEqual(m.valueOf(), [[0,0,0],[0,1,2],[0,3,4]]);
|
||||
m.subset(index(0, [0,3]), [5,6,7]); // unsqueezes the submatrix
|
||||
assert.deepEqual(m.valueOf(), [[5,6,7],[0,1,2],[0,3,4]]);
|
||||
});
|
||||
|
||||
it('should resize the matrix if the replacement subset is different size than selected subset', function() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user