Upperbound of range is now excluded

This commit is contained in:
josdejong 2013-08-09 22:09:46 +02:00
parent 70b48187a6
commit aa471db411
48 changed files with 136 additions and 127 deletions

View File

@ -2,13 +2,17 @@
https://github.com/josdejong/mathjs
## version 0.11.2
## version 0.12.0
*WARNING: version 0.12 is incompatible with previous versions.*
- Implemented functions `random([min, max])`, `randomInt([min, max])`,
`pickRandom(array)`. Thanks sebpiq.
- Implemented function `distribution(name)`, generating a distribution object
with functions `random`, `randomInt`, `pickRandom` for different
distributions. Currently supporting `uniform` and `normal`.
- Changed the behavior of `range` to exclude the upper bound, so `range(1, 4)`
now returns `[1, 2, 3]` instead of `[1, 2, 3, 4]`.
- Fixed zeros being formatted as null. Thanks TimKraft.

View File

@ -428,20 +428,21 @@ parser.eval('e = c(1, 0:end)'); // Matrix, [[43, 50]]
### Range
A `Range` creates a range with a start, end, and optionally a step.
The upper bound of the range is excluded.
A `Range` can be used to create indexes to get or set submatrices.
```js
var math = require('math.js');
math.factorial(math.range(1,5)); // Array, [1, 2, 6, 24, 120]
math.factorial(math.range(1,6)); // Array, [1, 2, 6, 24, 120]
var a = math.matrix(); // Matrix, []
a.set([math.range('2:5')], [7, 2, 1, 5]); // Matrix, [0, 7, 2, 1, 5]
a.set([math.range('2:6')], [7, 2, 1, 5]); // Matrix, [0, 7, 2, 1, 5]
var b = math.range(2, -1, -2); // Range, 2:-1:-2
var b = math.range(2, -1, -3); // Range, 2:-1:-3
var c = b.valueOf(); // Array, [2, 1, 0, -1, -2]
var d = math.eval('3:7'); // Range, 3:7
var d = math.eval('3:8'); // Range, 3:7
```
@ -542,7 +543,7 @@ types (Number, Complex, Unit, String, and Array) where applicable.
- math.matrix(x)
- math.number(x)
- math.parser()
- math.range(start [, step] , end)
- math.range(start, end [, step])
- math.string(x)
- math.unit(x)

View File

@ -56,7 +56,7 @@ console.log();
// get d sub matrix
// Matrix indexes are zero-based.
console.log('get a sub matrix');
var h = math.diag(math.range(1,3));
var h = math.diag(math.range(1,4));
print(h); // [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
print(h.get([[1, 2], [1, 2]])); // [[2, 0], [0, 3]]
console.log();
@ -77,10 +77,10 @@ console.log();
// create ranges
console.log('create ranges');
print(math.range(1,5).toArray()); // [1, 2, 3, 4, 5]
print(math.range(0, 3, 15).toArray()); // [0, 3, 6, 9, 12, 15]
print(math.range('2:-1:-2').toArray()); // [2, 1, 0, -1, -2]
print(math.factorial(math.range('1:5'))); // [1, 2, 6, 24, 120]
print(math.range(1,6).toArray()); // [1, 2, 3, 4, 5]
print(math.range(0, 3, 18).toArray()); // [0, 3, 6, 9, 12, 15]
print(math.range('2:-1:-3').toArray()); // [2, 1, 0, -1, -2]
print(math.factorial(math.range('1:6'))); // [1, 2, 6, 24, 120]
console.log();
console.log('use the expression parser');

View File

@ -1,16 +1,18 @@
var math = require('../../math.js'),
Node = require('./Node.js'),
var Node = require('./Node.js'),
SymbolNode = require('./SymbolNode.js').SymbolNode;
/**
* @constructor ParamsNode
* invoke a list with parameters on the results of a node
* @param {Object} math The math namespace containing all functions
* @param {Node} object
* @param {Node[]} params
* @param {Scope[]} paramScopes A scope for every parameter, where the
* index variable 'end' can be defined.
*/
function ParamsNode (object, params, paramScopes) {
function ParamsNode (math, object, params, paramScopes) {
this.subset = math.subset;
this.object = object;
this.params = params;
this.paramScopes = paramScopes;
@ -68,7 +70,7 @@ ParamsNode.prototype.eval = function() {
for (i = 0, len = this.params.length; i < len; i++) {
var paramScope = paramScopes[i];
if (paramScope) {
paramScope.set('end', size[i] - 1); // zero-based end
paramScope.set('end', size[i]);
}
}
}
@ -87,7 +89,7 @@ ParamsNode.prototype.eval = function() {
}
else {
// get a subset of the object
return math.subset(obj, results);
return this.subset(obj, results);
}
};

View File

@ -1,11 +1,11 @@
var math = require('../../math.js'),
Node = require('./Node.js'),
var Node = require('./Node.js'),
SymbolNode = require('./SymbolNode.js').SymbolNode;
/**
* @constructor UpdateNode
* Update a symbol value, like a(2,3) = 4.5
*
* @param {Object} math The math namespace containing all functions
* @param {String} name Symbol name
* @param {Node[] | undefined} params One or more parameters
* @param {Scope[]} paramScopes A scope for every parameter, where the
@ -13,7 +13,9 @@ var math = require('../../math.js'),
* @param {Node} expr The expression defining the symbol
* @param {Scope} scope Scope to store the result
*/
function UpdateNode(name, params, paramScopes, expr, scope) {
function UpdateNode(math, name, params, paramScopes, expr, scope) {
this.subset = math.subset;
this.name = name;
this.params = params;
this.paramScopes = paramScopes;
@ -73,7 +75,7 @@ UpdateNode.prototype.eval = function() {
for (var i = 0, len = this.params.length; i < len; i++) {
var paramScope = paramScopes[i];
if (paramScope) {
paramScope.set('end', size[i] - 1);
paramScope.set('end', size[i]);
}
}
}
@ -88,7 +90,7 @@ UpdateNode.prototype.eval = function() {
var exprResult = this.expr.eval();
// replace subset
result = math.subset(prevResult, paramResults, exprResult);
result = this.subset(prevResult, paramResults, exprResult);
this.scope.set(this.name, result);

View File

@ -536,7 +536,7 @@ module.exports = function (math) {
params = node.params;
paramScopes = node.paramScopes;
expr = parseAssignment(scope);
return new UpdateNode(name, params, paramScopes, expr, scope);
return new UpdateNode(math, name, params, paramScopes, expr, scope);
}
else {
throw createSyntaxError('Symbol expected at the left hand side ' +
@ -985,7 +985,7 @@ module.exports = function (math) {
}
getToken();
node = new ParamsNode(node, params, paramScopes);
node = new ParamsNode(math, node, params, paramScopes);
}
return node;

View File

@ -24,14 +24,14 @@ var util = require('../util/index.js'),
* range.toArray();
*
* Example usage:
* var c = new Range(2, 1, 5); // 2:1:5
* var c = new Range(2, 1, 6); // 2:1:5
* c.toArray(); // [2, 3, 4, 5]
* var d = new Range(2, -1, -2); // 2:-1:-2
* var d = new Range(2, -1, -3); // 2:-1:-2
* d.toArray(); // [2, 1, 0, -1, -2]
*
* @param {Number} start
* @param {Number} step
* @param {Number} end
* @param {Number} start included lower bound
* @param {Number} step step size
* @param {Number} end excluded upper bound
*/
function Range(start, step, end) {
if (!(this instanceof Range)) {
@ -58,7 +58,7 @@ function Range(start, step, end) {
* Parse a string into a range,
* The string contains the start, optional step, and end, separated by a colon.
* If the string does not contain a valid range, null is returned.
* For example str='0:2:10'.
* For example str='0:2:11'.
* @param {String} str
* @return {Range | null} range
*/
@ -115,10 +115,10 @@ Range.prototype.size = function () {
diff = end - start;
if (number.sign(step) == number.sign(diff)) {
len = Math.floor((diff) / step) + 1;
len = Math.floor((diff) / step);
}
else if (diff == 0) {
len = 1;
len = 0;
}
if (isNaN(len)) {
@ -140,14 +140,14 @@ Range.prototype.forEach = function (callback) {
var i = 0;
if (step > 0) {
while (x <= end) {
while (x < end) {
callback(x, i, this);
x += step;
i++;
}
}
else if (step < 0) {
while (x >= end) {
while (x > end) {
callback(x, i, this);
x += step;
i++;
@ -231,7 +231,7 @@ Range.prototype.valueOf = function () {
};
/**
* Get the string representation of the range, for example '2:5' or '0:0.2:10'
* Get the string representation of the range, for example '2:6' or '0:0.2:11'
* @returns {String} str
*/
Range.prototype.toString = function () {

View File

@ -122,8 +122,8 @@ describe('parser', function() {
it('should parse ranges', function() {
assert.ok(parser.eval('2:5') instanceof math.type.Range);
assert.deepEqual(parser.eval('2:5').toArray(), [2,3,4,5]);
assert.deepEqual(parser.eval('10:-2:2').toArray(), [10,8,6,4,2]);
assert.deepEqual(parser.eval('2:6').toArray(), [2,3,4,5]);
assert.deepEqual(parser.eval('10:-2:0').toArray(), [10,8,6,4,2]);
});
@ -134,24 +134,24 @@ describe('parser', function() {
[7,8,9]
]));
assert.deepEqual(parser.eval('a(1, :)'), matrix([[4,5,6]]));
assert.deepEqual(parser.eval('a(1, :1)'), matrix([[4,5]]));
assert.deepEqual(parser.eval('a(1, :2)'), matrix([[4,5]]));
assert.deepEqual(parser.eval('a(1, :end-1)'), matrix([[4,5]]));
assert.deepEqual(parser.eval('a(1, 1:)'), matrix([[5,6]]));
assert.deepEqual(parser.eval('a(1, 1:2)'), matrix([[5,6]]));
assert.deepEqual(parser.eval('a(1, 0:2:2)'), matrix([[4,6]]));
assert.deepEqual(parser.eval('a(1, 1:3)'), matrix([[5,6]]));
assert.deepEqual(parser.eval('a(1, 0:2:4)'), matrix([[4,6]]));
assert.deepEqual(parser.eval('a(:, 1)'), matrix([[2],[5],[8]]));
assert.deepEqual(parser.eval('a(:1, 1)'), matrix([[2],[5]]));
assert.deepEqual(parser.eval('a(:2, 1)'), matrix([[2],[5]]));
assert.deepEqual(parser.eval('a(:end-1, 1)'), matrix([[2],[5]]));
assert.deepEqual(parser.eval('a(1:, 1)'), matrix([[5],[8]]));
assert.deepEqual(parser.eval('a(1:2, 1)'), matrix([[5],[8]]));
assert.deepEqual(parser.eval('a(0:2:2, 1)'), matrix([[2],[8]]));
assert.deepEqual(parser.eval('a(1:3, 1)'), matrix([[5],[8]]));
assert.deepEqual(parser.eval('a(0:2:4, 1)'), matrix([[2],[8]]));
// TODO: implement and test support for Array (instead of Matrix)
});
it('should parse matrix resizings', function() {
assert.deepEqual(parser.eval('a = []'), matrix([[]]));
assert.deepEqual(parser.eval('a(0:2,0) = [1;2;3]'), matrix([[1],[2],[3]]));
assert.deepEqual(parser.eval('a(0:3,0) = [1;2;3]'), matrix([[1],[2],[3]]));
assert.deepEqual(parser.eval('a(:,1) = [4;5;6]'), matrix([[1,4],[2,5],[3,6]]));
assert.deepEqual(parser.eval('a = []'), matrix([[]]));
@ -163,7 +163,7 @@ describe('parser', function() {
assert.deepEqual(parser.eval('a(:,1) = [4;5;6]'), matrix([[0,4],[0,5],[3,6]]));
assert.deepEqual(parser.eval('a = []'), matrix([[]]));
assert.deepEqual(parser.eval('a(0,0:2) = [1,2,3]'), matrix([[1,2,3]]));
assert.deepEqual(parser.eval('a(0,0:3) = [1,2,3]'), matrix([[1,2,3]]));
assert.deepEqual(parser.eval('a(1,:) = [4,5,6]'), matrix([[1,2,3],[4,5,6]]));
});
@ -188,12 +188,12 @@ describe('parser', function() {
parser.eval('a(0,0) = 100');
assert.deepEqual(parser.get('a').size(), [2,2]);
assert.deepEqual(parser.get('a').valueOf(), [[100,2],[3,4]]);
parser.eval('a(1:2,1:2) = [10,11;12,13]');
parser.eval('a(1:3,1:3) = [10,11;12,13]');
assert.deepEqual(parser.get('a').size(), [3,3]);
assert.deepEqual(parser.get('a').valueOf(), [[100,2,0],[3,10,11],[0,12,13]]);
var a = parser.get('a');
assert.deepEqual(a.get([math.range('0:2'), math.range('0:1')]).valueOf(), [[100,2],[3,10],[0,12]]);
assert.deepEqual(parser.eval('a(0:2,0:1)').valueOf(), [[100,2],[3,10],[0,12]]);
assert.deepEqual(a.get([math.range('0:3'), math.range('0:2')]).valueOf(), [[100,2],[3,10],[0,12]]);
assert.deepEqual(parser.eval('a(0:3,0:2)').valueOf(), [[100,2],[3,10],[0,12]]);
});
@ -248,7 +248,7 @@ describe('parser', function() {
assert.deepEqual(parser.eval('c=[a,b;b,a]'), matrix([[1,2,5,6],[3,4,7,8],[5,6,1,2],[7,8,3,4]]));
assert.deepEqual(parser.eval('c=[[1,2]; [3,4]]'), matrix([[1,2],[3,4]]));
assert.deepEqual(parser.eval('c=[1; [2;3]]'), matrix([[1],[2],[3]]));
assert.deepEqual(parser.eval('d=1:3'), range(1,3)); // d is a Range
assert.deepEqual(parser.eval('d=1:4'), range(1,4)); // d is a Range
assert.deepEqual(parser.eval('[d,d]'), matrix([[1,2,3,1,2,3]]));
assert.deepEqual(parser.eval('[d;d]'), matrix([[1,2,3],[1,2,3]]));
assert.deepEqual(parser.eval('e=1+d'), [2,3,4]); // e is an Array
@ -267,9 +267,9 @@ describe('parser', function() {
assert.deepEqual(parser.eval('[1,2,3;4,5,6]\'').valueOf(), [[1,4],[2,5],[3,6]]);
assert.ok(parser.eval('[1,2,3;4,5,6]\'') instanceof math.type.Matrix);
assert.deepEqual(parser.eval('23\'').valueOf(), 23);
assert.deepEqual(parser.eval('[1:4]').valueOf(), [[1,2,3,4]]);
assert.deepEqual(parser.eval('[1:4]\'').valueOf(), [[1],[2],[3],[4]]);
assert.deepEqual(parser.eval('size([1:4])').valueOf(), [1, 4]);
assert.deepEqual(parser.eval('[1:5]').valueOf(), [[1,2,3,4]]);
assert.deepEqual(parser.eval('[1:5]\'').valueOf(), [[1],[2],[3],[4]]);
assert.deepEqual(parser.eval('size([1:5])').valueOf(), [1, 4]);
});

View File

@ -24,7 +24,7 @@ describe('abs', function () {
assert.ok(a1 instanceof math.type.Matrix);
assert.deepEqual(a1.size(), [3]);
assert.deepEqual(a1.valueOf(), [1,2,3]);
a1 = math.abs(math.range(-2,2));
a1 = math.abs(math.range(-2,3));
assert.ok(Array.isArray(a1));
assert.deepEqual(a1.length, 5);
assert.deepEqual(a1, [2,1,0,1,2])

View File

@ -50,7 +50,7 @@ describe('ceil', function() {
it('should ceil each element in a matrix, array or range', function() {
approx.deepEqual(ceil([1.2, 3.4, 5.6, 7.8, 10.0]), [2, 4, 6, 8, 10]);
approx.deepEqual(ceil(matrix([1.2, 3.4, 5.6, 7.8, 10.0])), matrix([2, 4, 6, 8, 10]));
approx.deepEqual(ceil(range(1.2, 2.2, 10)), [2, 4, 6, 8, 10]);
approx.deepEqual(ceil(range(1.2, 2.2, 11)), [2, 4, 6, 8, 10]);
});
});

View File

@ -41,7 +41,7 @@ describe('cube', function() {
// array, matrix, range
// arrays are evaluated element wise
assert.deepEqual(cube([2,3,4,5]), [8,27,64,125]);
assert.deepEqual(cube(range(2,5)), [8,27,64,125]);
assert.deepEqual(cube(range(2,6)), [8,27,64,125]);
assert.deepEqual(cube(matrix([2,3,4,5])), matrix([8,27,64,125]));
assert.deepEqual(cube(matrix([[1,2],[3,4]])), matrix([[1,8],[27,64]]));
});

View File

@ -62,7 +62,7 @@ describe('divide', function() {
});
it('should divide each elements in a matrix by a number', function() {
assert.deepEqual(divide(math.range(2,2,6), 2), [1,2,3]);
assert.deepEqual(divide(math.range(2,2,7), 2), [1,2,3]);
a = math.matrix([[1,2],[3,4]]);
assert.deepEqual(divide(a, 2), math.matrix([[0.5,1],[1.5,2]]));
assert.deepEqual(divide(a.valueOf(), 2), [[0.5,1],[1.5,2]]);

View File

@ -46,7 +46,7 @@ describe('edivide', function() {
});
it('should divide all the elements of a matrix by one number', function() {
assert.deepEqual(edivide(math.range(2,2,6), 2), [1,2,3]);
assert.deepEqual(edivide(math.range(2,2,7), 2), [1,2,3]);
a = math.matrix([[1,2],[3,4]]);
assert.deepEqual(edivide(a, 2), math.matrix([[0.5,1],[1.5,2]]));
assert.deepEqual(edivide(a.valueOf(), 2), [[0.5,1],[1.5,2]]);

View File

@ -67,7 +67,7 @@ describe('emultiply', function() {
it('should perform element-wise matrix multiplication', function() {
approx.deepEqual(emultiply(a, b), matrix([[5,12],[21,32]]));
approx.deepEqual(emultiply([[1,2],[3,4]], [[5,6],[7,8]]), [[5,12],[21,32]]);
approx.deepEqual(emultiply(range(1, 4), 2), [2, 4, 6, 8]);
approx.deepEqual(emultiply(range(1, 5), 2), [2, 4, 6, 8]);
});
it('should throw an error if matrices are of different sizes', function() {

View File

@ -61,7 +61,7 @@ describe('exp', function() {
it('should exponentiate matrices, arrays and ranges correctly', function() {
var res = [1, 2.71828182845905, 7.38905609893065, 20.0855369231877];
approx.deepEqual(exp([0,1,2,3]), res);
approx.deepEqual(exp(range('0:3')), res);
approx.deepEqual(exp(range('0:4')), res);
approx.deepEqual(exp(matrix([0,1,2,3])), matrix(res));
approx.deepEqual(exp(matrix([[0,1],[2,3]])),
matrix([[1, 2.71828182845905], [7.38905609893065, 20.0855369231877]]));

View File

@ -51,7 +51,7 @@ describe('fix ???', function() {
// matrix, array, range
approx.deepEqual(fix([1.2, 3.4, 5.6, 7.8, 10.0]), [1, 3, 5, 7, 10]);
approx.deepEqual(fix(matrix([1.2, 3.4, 5.6, 7.8, 10.0])), matrix([1, 3, 5, 7, 10]));
approx.deepEqual(fix(range(1.2, 2.2, 10)), [1, 3, 5, 7, 10]);
approx.deepEqual(fix(range(1.2, 2.2, 11)), [1, 3, 5, 7, 10]);
});
});

View File

@ -47,7 +47,7 @@ describe('floor', function() {
it('should floor all elements in a matrix', function() {
approx.deepEqual(floor([1.2, 3.4, 5.6, 7.8, 10.0]), [1, 3, 5, 7, 10]);
approx.deepEqual(floor(matrix([1.2, 3.4, 5.6, 7.8, 10.0])), matrix([1, 3, 5, 7, 10]));
approx.deepEqual(floor(range(1.2, 2.2, 10)), [1, 3, 5, 7, 10]);
approx.deepEqual(floor(range(1.2, 2.2, 11)), [1, 3, 5, 7, 10]);
});
});

View File

@ -59,7 +59,7 @@ describe('log', function() {
it('should return the log of each element of a matrix', function() {
var res = [0, 0.693147180559945, 1.098612288668110, 1.386294361119891];
approx.deepEqual(log([1,2,3,4]), res);
approx.deepEqual(log(range('1:4')), res);
approx.deepEqual(log(range('1:5')), res);
approx.deepEqual(log(matrix([1,2,3,4])), matrix(res));
approx.deepEqual(log(matrix([[1,2],[3,4]])),
matrix([[0, 0.693147180559945], [1.098612288668110, 1.386294361119891]]));

View File

@ -57,7 +57,7 @@ describe('log10', function() {
it('should return the log base 10 of each element of a matrix', function() {
var res = [0, 0.301029995663981, 0.477121254719662, 0.602059991327962];
approx.deepEqual(log10([1,2,3,4]), res);
approx.deepEqual(log10(range('1:4')), res);
approx.deepEqual(log10(range('1:5')), res);
approx.deepEqual(log10(matrix([1,2,3,4])), matrix(res));
approx.deepEqual(math.divide(log10(matrix([1,2,3,4])), math.LOG10E),
matrix([0, 0.693147180559945, 1.098612288668110, 1.386294361119891]));

View File

@ -45,7 +45,7 @@ describe('mod', function() {
it('should perform element-wise modulus on a matrix', function() {
approx.deepEqual(mod([-4,-3,-2,-1,0,1,2,3,4], 3), [2,0,1,2,0,1,2,0,1]);
approx.deepEqual(mod(matrix([-4,-3,-2,-1,0,1,2,3,4]), 3), matrix([2,0,1,2,0,1,2,0,1]));
approx.deepEqual(mod(range(-4,4), 3), [2,0,1,2,0,1,2,0,1]);
approx.deepEqual(mod(range(-4,5), 3), [2,0,1,2,0,1,2,0,1]);
});
});

View File

@ -105,7 +105,7 @@ describe('multiply', function() {
approx.deepEqual(multiply(d, b), matrix([[67,78]]));
approx.deepEqual(multiply(d, c), matrix([[61]]));
approx.deepEqual(multiply([[1,2],[3,4]], [[5,6],[7,8]]), [[19,22],[43,50]]);
approx.deepEqual(multiply(range(1, 4), 2), [2, 4, 6, 8]);
approx.deepEqual(multiply(range(1, 5), 2), [2, 4, 6, 8]);
});
it('should throw an error if multiplying matrices with incompatible sizes', function() {

View File

@ -29,8 +29,8 @@ describe('sign', function() {
});
it('should return a matrix of the signs of each elements in the given matrix', function() {
assert.deepEqual(math.sign(math.range(-2,2)), [-1,-1,0,1,1]);
assert.deepEqual(math.sign(math.matrix(math.range(-2,2))).valueOf(), [-1,-1,0,1,1]);
assert.deepEqual(math.sign(math.range(-2,3)), [-1,-1,0,1,1]);
assert.deepEqual(math.sign(math.matrix(math.range(-2,3))).valueOf(), [-1,-1,0,1,1]);
assert.deepEqual(math.sign([-2, -1, 0, 1, 2]), [-1,-1,0,1,1]);
});

View File

@ -35,7 +35,7 @@ describe('sqrt', function() {
assert.deepEqual(math.sqrt([4,9,16,25]), [2,3,4,5]);
assert.deepEqual(math.sqrt([[4,9],[16,25]]), [[2,3],[4,5]]);
assert.deepEqual(math.sqrt(math.matrix([[4,9],[16,25]])), math.matrix([[2,3],[4,5]]));
approx.deepEqual(math.sqrt(math.range('4:2:8')), [2, 2.44948974278318, 2.82842712474619]);
approx.deepEqual(math.sqrt(math.range('4:2:10')), [2, 2.44948974278318, 2.82842712474619]);
});
});

View File

@ -39,7 +39,7 @@ describe('square', function() {
it('should return the square of each element in a matrix', function() {
assert.deepEqual(square([2,3,4,5]), [4,9,16,25]);
assert.deepEqual(square(range(2,5)), [4,9,16,25]);
assert.deepEqual(square(range(2,6)), [4,9,16,25]);
assert.deepEqual(square(matrix([2,3,4,5])), matrix([4,9,16,25]));
assert.deepEqual(square(matrix([[1,2],[3,4]])), matrix([[1,4],[9,16]]));
});

View File

@ -57,7 +57,7 @@ describe('subtract', function() {
assert.ok(a6 instanceof math.type.Matrix);
assert.deepEqual(a6.size(), [2,2]);
assert.deepEqual(a6.valueOf(), [[-4,-4],[-4,-4]]);
assert.deepEqual(math.subtract(math.range(1,5), 2), math.range(-1,3).valueOf());
assert.deepEqual(math.subtract(math.range(1,6), 2), math.range(-1,4).valueOf());
});
});

View File

@ -45,7 +45,7 @@ describe('unaryminus', function() {
assert.deepEqual(a7.size(), [2,2]);
assert.deepEqual(a7.valueOf(), [[-1,-2],[-3,-4]]);
assert.deepEqual(math.unary([[1,2],[3,4]]), [[-1,-2],[-3,-4]]);
assert.deepEqual(math.unary(math.range(1,5)), math.range(-1,-1,-5).valueOf());
assert.deepEqual(math.unary(math.range(1,6)), math.range(-1,-1,-6).valueOf());
});
});

View File

@ -27,7 +27,7 @@ describe('matrix', function() {
});
it('should create a matrix from a range correctly', function() {
var d = matrix(math.range(1,5));
var d = matrix(math.range(1,6));
assert.ok(d instanceof math.type.Matrix);
assert.deepEqual(d, new math.type.Matrix([1,2,3,4,5]));
assert.deepEqual(math.size(d), matrix([5]));

View File

@ -5,20 +5,20 @@ var assert = require('assert'),
describe('range', function() {
it('should parse a valid string correctly', function() {
assert.deepEqual(range('1:5').valueOf(), [1,2,3,4,5]);
assert.deepEqual(range('0:2:8').valueOf(), [0,2,4,6,8]);
assert.deepEqual(range('5:-1:1').valueOf(), [5,4,3,2,1]);
assert.deepEqual(range('2:-2:-2').valueOf(), [2,0,-2]);
assert.deepEqual(range('1:6').valueOf(), [1,2,3,4,5]);
assert.deepEqual(range('0:2:10').valueOf(), [0,2,4,6,8]);
assert.deepEqual(range('5:-1:0').valueOf(), [5,4,3,2,1]);
assert.deepEqual(range('2:-2:-3').valueOf(), [2,0,-2]);
});
it('should create a range start:1:end if called with 2 numbers', function() {
var a = range(1,5);
var a = range(1,6);
var b = range(a);
a.start = 3;
assert.deepEqual(a.valueOf(), [3,4,5]);
assert.deepEqual(b.valueOf(), [1,2,3,4,5]);
assert.deepEqual(range(1,5).valueOf(), [1,2,3,4,5]);
assert.deepEqual(range(5,1).valueOf(), []);
assert.deepEqual(range(1,6).valueOf(), [1,2,3,4,5]);
assert.deepEqual(range(6,1).valueOf(), []);
});
it('should throw an error if called with an invalid string', function() {
@ -38,9 +38,9 @@ describe('range', function() {
});
it('should create a range start:step:end if called with 3 numbers', function() {
assert.deepEqual(range(0,2,8).valueOf(), [0,2,4,6,8]);
assert.deepEqual(range(5,-1,1).valueOf(), [5,4,3,2,1]);
assert.deepEqual(range(2,-2,-2).valueOf(), [2,0,-2]);
assert.deepEqual(range(0,2,10).valueOf(), [0,2,4,6,8]);
assert.deepEqual(range(5,-1,0).valueOf(), [5,4,3,2,1]);
assert.deepEqual(range(2,-2,-4).valueOf(), [2,0,-2]);
});
it('should throw an error if called with one invalid argument', function() {

View File

@ -7,7 +7,7 @@ describe('string', function() {
it('should be parsed correctly', function() {
assert.equal(math.eval('string(123)'), '123');
assert.equal(math.eval('string(2+3i)'), '2 + 3i');
assert.equal(math.eval('string(1:5)'), '[1, 2, 3, 4, 5]');
assert.equal(math.eval('string(1:6)'), '[1, 2, 3, 4, 5]');
assert.equal(math.eval('string(2 inch)'), '2 inch');
assert.equal(math.eval('string([1,2;3,4])'), '[[1, 2], [3, 4]]');
});
@ -45,7 +45,7 @@ describe('string', function() {
it('should convert a matrix/range/array to string', function() {
assert.equal(string([[1,2],[3,4]]), '[[1, 2], [3, 4]]');
assert.equal(string(math.matrix([[1,2],[3,4]])), '[[1, 2], [3, 4]]');
assert.equal(string(math.range(1,5)), '[1, 2, 3, 4, 5]');
assert.equal(string(math.range(1,6)), '[1, 2, 3, 4, 5]');
});
it('should throw an error if called with wrong number of arguments', function() {

View File

@ -4,7 +4,7 @@ var math = require('../../../src/index.js');
assert.equal(math.det(3), 3);
assert.equal(math.det([5]), 5);
assert.equal(math.det(math.range(2,2)), 2);
assert.equal(math.det(math.range(2,3)), 2);
assert.equal(math.det([[1,2],[3,4]]), -2);
assert.equal(math.det(math.matrix([[1,2],[3,4]])), -2);
assert.equal(math.det([

View File

@ -9,6 +9,6 @@ assert.deepEqual(math.diag([[1,2,3],[4,5,6]]).valueOf(), [1,5]);
assert.deepEqual(math.diag([[1,2,3],[4,5,6]],1).valueOf(), [2,6]);
assert.deepEqual(math.diag([[1,2,3],[4,5,6]],-1).valueOf(), [4]);
assert.deepEqual(math.diag([[1,2,3],[4,5,6]],-2).valueOf(), []);
assert.deepEqual(math.diag(math.range(1,3)).valueOf(), [[1,0,0],[0,2,0],[0,0,3]]);
assert.deepEqual(math.diag(math.range(1,4)).valueOf(), [[1,0,0],[0,2,0],[0,0,3]]);
assert.throws(function () {math.diag([[[1],[2]],[[3],[4]]])});
// TODO: test diag for all types of input (also scalar)

View File

@ -19,5 +19,5 @@ assert.deepEqual(math.size(math.complex(2,3)), []);
assert.deepEqual(math.size(null), []);
assert.deepEqual(math.size(math.matrix()), math.matrix([0]));
assert.deepEqual(math.size(math.matrix([[1,2,3], [4,5,6]])), math.matrix([2,3]));
assert.deepEqual(math.size(math.range(2,5)), [4]);
assert.deepEqual(math.size(math.range(2,6)), [4]);
// TODO: test whether math.size throws an error in case of invalid data or size

View File

@ -13,4 +13,4 @@ m = math.ones(3,1,1);
assert.deepEqual(size(m), matrix([3,1,1]));
assert.deepEqual(size(squeeze(m)), matrix([3]));
assert.deepEqual(squeeze(2.3), 2.3);
assert.deepEqual(size(squeeze(math.range(1,5))), [5]);
assert.deepEqual(size(squeeze(math.range(1,6))), [5]);

View File

@ -21,7 +21,7 @@ assert.throws(function () {subset(a, [1.3, 0])}, TypeError);
// matrix
var b = math.matrix(a);
assert.deepEqual(subset(b, [[0,1], 1]), matrix([[2],[4]]));
assert.deepEqual(subset(b, [range(0,1), [1]]), matrix([[2],[4]]));
assert.deepEqual(subset(b, [range(0,2), [1]]), matrix([[2],[4]]));
assert.deepEqual(subset(b, [matrix([0,1]), [1]]), matrix([[2],[4]]));
assert.deepEqual(subset(b, [1, 0]), 3);
assert.deepEqual(subset(b, matrix([1, 0])), 3);
@ -32,17 +32,17 @@ assert.throws(function () {subset(b, [1,0,0])}, RangeError);
assert.throws(function () {subset(b, [1.3, 0])}, TypeError);
// range
var c = math.diag(math.range(1,5));
assert.deepEqual(subset(c, [1, range('0:4')]), matrix([[0,2,0,0,0]]));
assert.deepEqual(subset(c, [range('1:2'), range('0:4')]), matrix([[0,2,0,0,0],[0,0,3,0,0]]));
var c = math.diag(math.range(1,6));
assert.deepEqual(subset(c, [1, range('0:5')]), matrix([[0,2,0,0,0]]));
assert.deepEqual(subset(c, [range('1:3'), range('0:5')]), matrix([[0,2,0,0,0],[0,0,3,0,0]]));
assert.throws(function () {subset(c, [1, range('2:5')])}, RangeError);
assert.throws(function () {subset(c, [1, range('2:6')])}, RangeError);
assert.throws(function () {subset(c, [1.3, 0])}, TypeError);
// string
assert.deepEqual(subset('hello', [1]), 'e');
assert.deepEqual(subset('hello', [[1]]), 'e');
assert.deepEqual(subset('hello', [range('4:-1:0')]), 'olleh');
assert.deepEqual(subset('hello', [range('4:-1:-1')]), 'olleh');
assert.deepEqual(subset('hello', [[0,4]]), 'ho');
assert.throws(function () {subset('hello', 1)}, RangeError);
@ -94,7 +94,7 @@ assert.throws(function () {subset(d, [1], 123)}, RangeError);
assert.throws(function () {subset(d, [1.3,0], 123)}, TypeError);
// range
assert.deepEqual(subset(range('1:5'), [range('1:3')], range('4:-1:2')), [1,4,3,2,5]);
assert.deepEqual(subset(range('1:6'), [range('1:4')], range('4:-1:1')), [1,4,3,2,5]);
// string
var j = 'hello';
@ -102,7 +102,7 @@ assert.deepEqual(subset(j, [[0,5]], 'H!'), 'Hello!');
assert.deepEqual(j, 'hello');
assert.deepEqual(subset(j, [0], 'H'), 'Hello');
assert.deepEqual(j, 'hello');
assert.deepEqual(subset(j, [range(5,10)], ' world'), 'hello world');
assert.deepEqual(subset(j, [range(5,11)], ' world'), 'hello world');
assert.deepEqual(j, 'hello');
assert.throws(function () {subset('hello', [[1,2]], '1234')}, RangeError);
@ -132,9 +132,9 @@ assert.deepEqual(parser.eval('b(0)'), 123);
assert.deepEqual(parser.eval('b(0)=456'), 456);
assert.deepEqual(parser.eval('b'), 456);
assert.deepEqual(parser.eval('c="hello"'), "hello");
assert.deepEqual(parser.eval('c(1:3)'), "ell");
assert.deepEqual(parser.eval('c(1:4)'), "ell");
assert.deepEqual(parser.eval('c(0) = "H"'), "Hello");
assert.deepEqual(parser.eval('c'), "Hello");
assert.deepEqual(parser.eval('c(5:10) = " world"'), "Hello world");
assert.deepEqual(parser.eval('c(4:-1:0)'), "olleH");
assert.deepEqual(parser.eval('c(end:-1:0)'), "dlrow olleH");
assert.deepEqual(parser.eval('c(5:11) = " world"'), "Hello world");
assert.deepEqual(parser.eval('c(4:-1:-1)'), "olleH");
assert.deepEqual(parser.eval('c(end-1:-1:-1)'), "dlrow olleH");

View File

@ -8,7 +8,7 @@ assert.equal(math.factorial(2), 2);
assert.equal(math.factorial(3), 6);
assert.equal(math.factorial(4), 24);
assert.equal(math.factorial(5), 120);
assert.deepEqual(math.factorial(math.range(0,5)), [1,1,2,6,24,120]);
assert.deepEqual(math.factorial(math.range(0,6)), [1,1,2,6,24,120]);
assert.throws(function() { math.factorial(-1); });
assert.throws(function() { math.factorial(1.5); });
assert.throws(function() { math.factorial(); });

View File

@ -10,8 +10,8 @@ assert.equal(math.max(0,0,0,0), 0);
assert.equal(math.max('A', 'C', 'D', 'B'), 'D');
assert.equal(math.max([1,3,5,2,-5]), 5);
assert.equal(math.max(math.matrix([1,3,5,2,-5])), 5);
assert.equal(math.max(math.range(1,5)), 5);
assert.equal(math.max(math.range(5,-1,2)), 5);
assert.equal(math.max(math.range(1,6)), 5);
assert.equal(math.max(math.range(5,-1,1)), 5);
assert.throws(function() {math.max()});
assert.throws(function() {math.max([5,2], 3)});
assert.throws(function() {math.max([])});

View File

@ -10,8 +10,8 @@ assert.equal(math.min(0,0,0,0), 0);
assert.equal(math.min('A', 'C', 'D', 'B'), 'A');
assert.equal(math.min([1,3,5,-5,2]), -5);
assert.equal(math.min(math.matrix([1,3,5,-5,2])), -5);
assert.equal(math.min(math.range(1,5)), 1);
assert.equal(math.min(math.range(5,-1,2)), 2);
assert.equal(math.min(math.range(1,6)), 1);
assert.equal(math.min(math.range(5,-1,1)), 2);
assert.throws(function() {math.min()});
assert.throws(function() {math.min([5,2], 3)});
assert.throws(function() {math.min([])});

View File

@ -44,5 +44,5 @@ approx.equal(acos(cos(2)), 2);
// the next tests are verified with mathematica
var acos123 = [0, complex(0, 1.316957896924817), complex(0, 1.762747174039086)];
approx.deepEqual(acos([1,2,3]), acos123);
approx.deepEqual(acos(math.range('1:3')), acos123);
approx.deepEqual(acos(math.range('1:4')), acos123);
approx.deepEqual(acos(matrix([1,2,3])), matrix(acos123));

View File

@ -49,5 +49,5 @@ var asin123 = [
complex(1.57079632679490, -1.31695789692482),
complex(1.57079632679490, -1.76274717403909)];
approx.deepEqual(asin([1,2,3]), asin123);
approx.deepEqual(asin(math.range('1:3')), asin123);
approx.deepEqual(asin(math.range('1:4')), asin123);
approx.deepEqual(asin(matrix([1,2,3])), matrix(asin123));

View File

@ -44,5 +44,5 @@ approx.equal(atan(tan(2)), -1.14159265358979);
// matrix, array, range
var atan123 = [0.785398163397448, 1.107148717794090, 1.249045772398254];
approx.deepEqual(atan([1,2,3]), atan123);
approx.deepEqual(atan(math.range('1:3')), atan123);
approx.deepEqual(atan(math.range('1:4')), atan123);
approx.deepEqual(atan(matrix([1,2,3])), matrix(atan123));

View File

@ -43,5 +43,5 @@ assert.throws(function () {cos('string')});
// array, matrix, range
var cos123 = [0.540302305868140, -0.41614683654714, -0.989992496600445];
approx.deepEqual(cos([1,2,3]), cos123);
approx.deepEqual(cos(math.range('1:3')), cos123);
approx.deepEqual(cos(math.range('1:4')), cos123);
approx.deepEqual(cos(matrix([1,2,3])), matrix(cos123));

View File

@ -42,5 +42,5 @@ assert.throws(function () {cot('string')});
// array, matrix, range
var cot123 = [0.642092615934331, -0.457657554360286, -7.015252551434534];
approx.deepEqual(cot([1,2,3]), cot123);
approx.deepEqual(cot(math.range('1:3')), cot123);
approx.deepEqual(cot(math.range('1:4')), cot123);
approx.deepEqual(cot(matrix([1,2,3])), matrix(cot123));

View File

@ -43,5 +43,5 @@ assert.throws(function () {csc('string')});
// array, matrix, range
var csc123 = [1.18839510577812, 1.09975017029462, 7.08616739573719];
approx.deepEqual(csc([1,2,3]), csc123);
approx.deepEqual(csc(math.range('1:3')), csc123);
approx.deepEqual(csc(math.range('1:4')), csc123);
approx.deepEqual(csc(matrix([1,2,3])), matrix(csc123));

View File

@ -51,5 +51,5 @@ assert.throws(function () {sec('string')});
// array, matrix, range
var sec123 = [1.85081571768093, -2.40299796172238, -1.01010866590799];
approx.deepEqual(sec([1,2,3]), sec123);
approx.deepEqual(sec(math.range('1:3')), sec123);
approx.deepEqual(sec(math.range('1:4')), sec123);
approx.deepEqual(sec(matrix([1,2,3])), matrix(sec123));

View File

@ -43,5 +43,5 @@ assert.throws(function () {sin('string')});
// array, matrix, range
var sin123 = [0.84147098480789, 0.909297426825682, 0.141120008059867];
approx.deepEqual(sin([1,2,3]), sin123);
approx.deepEqual(sin(math.range('1:3')), sin123);
approx.deepEqual(sin(math.range('1:4')), sin123);
approx.deepEqual(sin(matrix([1,2,3])), matrix(sin123));

View File

@ -49,5 +49,5 @@ math.range(0, 0.1, 1).forEach(function (value) {
// array, matrix, range
var tan123 = [1.557407724654902, -2.185039863261519, -0.142546543074278];
approx.deepEqual(tan([1,2,3]), tan123);
approx.deepEqual(tan(math.range('1:3')), tan123);
approx.deepEqual(tan(math.range('1:4')), tan123);
approx.deepEqual(tan(matrix([1,2,3])), matrix(tan123));

View File

@ -108,7 +108,7 @@ assert.deepEqual(m.size(), [2,3]);
assert.deepEqual(m.valueOf(), [[0,0,0],[0,0,5]]);
// get 1-dimensional
m = math.matrix(math.range(0,9));
m = math.matrix(math.range(0,10));
assert.deepEqual(m.size(), [10]);
assert.deepEqual(m.get([[2,5,3,4]]).valueOf(), [2,5,3,4]);
@ -117,10 +117,10 @@ m = math.matrix([[1,2,3],[4,5,6],[7,8,9]]);
assert.deepEqual(m.size(), [3,3]);
assert.deepEqual(m.get([1,1]), 5);
assert.deepEqual(m.get([[0,1],[0,1]]).valueOf(), [[1,2],[4,5]]);
assert.deepEqual(m.get([[1], math.range(1,2)]).valueOf(), [[5,6]]);
assert.deepEqual(m.get([0, math.range(1,2)]).valueOf(), [[2,3]]);
assert.deepEqual(m.get([math.range(1,2), [1]]).valueOf(), [[5],[8]]);
assert.deepEqual(m.get([math.range(1,2), 2]).valueOf(), [[6],[9]]);
assert.deepEqual(m.get([[1], math.range(1,3)]).valueOf(), [[5,6]]);
assert.deepEqual(m.get([0, math.range(1,3)]).valueOf(), [[2,3]]);
assert.deepEqual(m.get([math.range(1,3), [1]]).valueOf(), [[5],[8]]);
assert.deepEqual(m.get([math.range(1,3), 2]).valueOf(), [[6],[9]]);
// get n-dimensional
m = math.matrix([[[1,2],[3,4]], [[5,6],[7,8]]]);
@ -132,7 +132,7 @@ assert.deepEqual(m.get([[1],[1],[0,1]]).valueOf(), [[[7,8]]]);
assert.deepEqual(m.get([[1],[0,1],[1]]).valueOf(), [[[6],[8]]]);
// set 1-dimensional
m = math.matrix(math.range(0,6));
m = math.matrix(math.range(0,7));
m.set([[2,3]], [20,30]);
assert.deepEqual(m.size(), [7]);
assert.deepEqual(m.valueOf(), [0,1,20,30,4,5,6]);
@ -162,7 +162,7 @@ assert.deepEqual(m.size(), [1]);
m.set([[1,2], [1,2]], [[1,2],[3,4]]);
assert.deepEqual(m.size(), [3,3]);
assert.deepEqual(m.valueOf(), [[123,0,0],[0,1,2],[0,3,4]]);
m.set([math.range(0,1), math.range(0,1)], [[55,55],[55,55]]);
m.set([math.range(0,2), math.range(0,2)], [[55,55],[55,55]]);
assert.deepEqual(m.size(), [3,3]);
assert.deepEqual(m.valueOf(), [[55,55,0],[55,55,2],[0,3,4]]);

View File

@ -3,15 +3,15 @@
var assert = require('assert');
var math = require('../../src/index.js');
var r = math.range(2,5);
var r = math.range(2,6);
assert.deepEqual(r.toArray(), [2,3,4,5]);
assert.equal(r.size(), 4);
r = math.range(10, -1, 5);
r = math.range(10, -1, 4);
assert.deepEqual(r.toArray(), [10,9,8,7,6,5]);
assert.equal(r.size(), 6);
r = math.range(1, 1.5, 5);
r = math.range(1, 1.5, 5.5);
assert.deepEqual(r.toArray(), [1,2.5,4]);
assert.equal(r.size(), 3);
@ -19,7 +19,7 @@ assert.throws(function () {
var r = math.range();
});
r = math.range(0,0);
r = math.range(0,1);
assert.deepEqual(r.toArray(), [0]);
assert.equal(r.size(), 1);
@ -33,13 +33,13 @@ assert.deepEqual(r.toArray(), []);
assert.equal(r.size(), 0);
// test range parse
r = math.range('10:-1:5');
r = math.range('10:-1:4');
assert.deepEqual(r.toArray(), [10,9,8,7,6,5]);
assert.equal(r.size(), 6);
r = math.range('2 : 5');
r = math.range('2 : 6');
assert.deepEqual(r.toArray(), [2,3,4,5]);
assert.equal(r.size(), 4);
assert.throws(function () {math.range('a:3');});
assert.throws(function () {math.range('a:4');});
assert.throws(function () {math.range('3');});
assert.throws(function () {math.range(3);});
assert.throws(function () {math.range('');});