Added some comments to the derivative file. Added some test cases as well (explicitly test partial derivatives and pure JS usage).

This commit is contained in:
Favian Contreras 2015-09-19 21:24:56 -07:00
parent 31cdd6db1f
commit 48bb64af4e
2 changed files with 55 additions and 4 deletions

View File

@ -52,6 +52,8 @@ function factory (type, config, load, typed) {
},
'Object, SymbolNode, string': function (constNodes, node, varName) {
// Treat other variables like constants. For reasoning, see:
// https://en.wikipedia.org/wiki/Partial_derivative
if (node.name != varName) {
return constNodes[node] = true;
}
@ -126,8 +128,8 @@ function factory (type, config, load, typed) {
var arg1 = node.args[0];
var arg2;
var div = false;
var negative = false;
var div = false; // is output a fraction?
var negative = false; // is output negative?
var funcDerivative;
switch (node.name) {
@ -589,7 +591,10 @@ function factory (type, config, load, typed) {
return;
}
// Avoids unidentified symbol error
// There should be an incorrect number of arguments if we reach here
// Change all args to constants to avoid unidentified
// symbol error when compiling function
for (var i = 0; i < node.args.length; ++i) {
node.args[i] = new ConstantNode(0);
}

View File

@ -16,7 +16,6 @@ describe('derivative', function() {
it('should take the derivative of a SymbolNodes', function() {
assert.deepEqual(math.eval('derivative(x, x)'), new ConstantNode(1));
assert.deepEqual(math.eval('derivative(C, x)'), new ConstantNode(0));
});
it('should maintain parenthesis of ParenthesisNodes', function() {
@ -281,6 +280,53 @@ describe('derivative', function() {
]));
});
it('should take the partial derivative of an expression', function() {
assert.deepEqual(math.eval('derivative(x + y, x)'), math.parse('1 + 0'));
assert.deepEqual(math.eval('derivative(x + log(y)*y, x)'), math.parse('1 + 0'));
assert.deepEqual(math.eval('derivative(x + y + z, x)'), math.parse('1 + 0 + 0'));
assert.deepEqual(math.eval('derivative(x + log(y)*z, x)'), math.parse('1 + 0'));
assert.deepEqual(math.eval('derivative(x + log(y)*x, x)'), math.parse('1 + log(y)*1'));
// 2 * 1 * x ^ (2 - 1) + y * 1 + 0 = 2x + y
assert.deepEqual(math.eval('derivative(x^2 + x*y + y^2, x)'), new OperatorNode('+', 'add', [
new OperatorNode('+', 'add', [
new OperatorNode('*', 'multiply', [
new ConstantNode(2),
new OperatorNode('*', 'multiply', [
new ConstantNode(1),
new OperatorNode('^', 'pow', [
new SymbolNode('x'),
math.parse('2 - 1')
])
])
]),
math.parse('y * 1')
]),
new ConstantNode(0)
]));
});
it('should function properly even without being called within an eval', function() {
var f = math.parse('2x^3');
// 2*3*1*x^(3-1) = 6x^2
assert.deepEqual(math.derivative(f, new SymbolNode('x')), new OperatorNode('*', 'multiply', [
new ConstantNode(2),
new OperatorNode('*', 'multiply', [
new ConstantNode(3),
new OperatorNode('*', 'multiply', [
new ConstantNode(1),
new OperatorNode('^', 'pow', [
new SymbolNode('x'),
math.parse('3 - 1')
])
])
])
]));
});
it('should throw error if expressions contain unsupported operators or functions', function() {
assert.throws(function () { math.eval('derivative(x << 2, x)'); }, /Error: Operator "<<" not supported by derivative/);
assert.throws(function () { math.eval('derivative(subset(x), x)'); }, /Error: Function "subset" not supported by derivative/);