diff --git a/Algebra.js b/Algebra.js index ebfd01d8..3a88a2a5 100644 --- a/Algebra.js +++ b/Algebra.js @@ -32,7 +32,7 @@ if((typeof module) !== 'undefined') { isInt = core.Utils.isInt, Symbol = core.Symbol, CONST_HASH = core.Settings.CONST_HASH; - + //*************** CLASSES ***************// /** * Converts a symbol into an equivalent polynomial arrays of @@ -2835,8 +2835,8 @@ if((typeof module) !== 'undefined') { MVTerm: MVTerm } }; - - nerdamer.useAlgebraDiv = function() { + + nerdamer.useAlgebraDiv = function() { var divide = __.divideFn = _.divide; var calls = 0; //keep track of how many calls were made _.divide = function(a, b) { diff --git a/Calculus.js b/Calculus.js index db573e3e..98842afc 100644 --- a/Calculus.js +++ b/Calculus.js @@ -462,6 +462,9 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') { case ATAN: symbol = _.parse('(1+('+text(symbol.args[0])+')^2)^(-1)'); break; + case 'acot': + symbol = _.parse('-1/(('+symbol.args[0]+')^2+1)'); + break; case ABS: m = symbol.multiplier.clone(); symbol.toUnitMultiplier(); @@ -494,6 +497,10 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') { // Use a clone if this gives errors symbol = qdiff(symbol, '-tanh'); break; + case 'csch': + var arg = String(symbol.args[0]); + return _.parse('-coth('+arg+')*csch('+arg+')'); + break; case 'asinh': symbol = _.parse('(sqrt(1+('+text(symbol.args[0])+')^2))^(-1)'); break; @@ -503,6 +510,17 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') { case 'atanh': symbol = _.parse('(1-('+text(symbol.args[0])+')^2)^(-1)'); break; + case 'asech': + var arg = String(symbol.args[0]); + symbol = _.parse('-1/(sqrt(1/('+arg+')^2-1)*('+arg+')^2)'); + break; + case 'acoth': + symbol = _.parse('-1/(('+symbol.args[0]+')^2-1)'); + break; + case 'acsch': + var arg = String(symbol.args[0]); + symbol = _.parse('-1/(sqrt(1/('+arg+')^2+1)*('+arg+')^2)'); + break; case 'Si': var arg = symbol.args[0]; symbol = _.parse('sin('+arg+')/('+arg+')'); @@ -523,6 +541,22 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') { var arg = symbol.args[0]; symbol = _.parse('e^('+arg+')/('+arg+')'); break; + case 'erf': + symbol = _.parse('(2*e^(-('+symbol.args[0]+')^2))/sqrt(pi)'); + break; + case 'atan2': + var x_ = String(symbol.args[0]), + y_ = String(symbol.args[1]); + symbol = _.parse('('+y_+')/(('+y_+')^2+('+x_+')^2)'); + break; + case 'sign': + symbol = new Symbol(0); + break; + case 'log10': + symbol = _.parse('1/(('+symbol.args[0]+')*log(10))'); + break; + default: + symbol = _.symfunction('diff', [symbol, wrt]); } } else if(g === EX || g === FN && isSymbol(symbol.power)) { @@ -1913,4 +1947,4 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') { ]); //link registered functions externally nerdamer.api(); -})(); +})(); \ No newline at end of file diff --git a/nerdamer.core.js b/nerdamer.core.js index ac309f33..5691823f 100644 --- a/nerdamer.core.js +++ b/nerdamer.core.js @@ -3591,6 +3591,10 @@ var nerdamer = (function(imports) { 'vecset' : [ vecset, 3], 'matget' : [ matget, 3], 'matset' : [ matset, 4], + 'matgetrow' : [ matgetrow, 2], + 'matsetrow' : [ matsetrow, 3], + 'matgetcol' : [ matgetcol, 2], + 'matsetcol' : [ matsetcol, 3], 'IF' : [ IF, 3], //imaginary support 'realpart' : [ realpart, 1], @@ -4441,13 +4445,15 @@ var nerdamer = (function(imports) { * @returns {Symbol} */ function mod(symbol1, symbol2) { - if(!symbol2) - return _.divide(symbol2, new Symbol(100)); if(symbol1.isConstant() && symbol2.isConstant()) { var retval = new Symbol(1); retval.multiplier = retval.multiplier.multiply(symbol1.multiplier.mod(symbol2.multiplier)); return retval; } + //try to see if division has remainder of zero + var r = _.divide(symbol1.clone(), symbol2.clone()); + if(isInt(r)) + return new Symbol(0); return _.symfunction('mod', [symbol1, symbol2]); } /** @@ -5146,6 +5152,40 @@ var nerdamer = (function(imports) { return matrix.elements[i][j]; } + function matgetrow(matrix, i) { + return new Matrix(matrix.elements[i]); + } + + function matsetrow(matrix, i, x) { + if(matrix.elements[i].length !== x.elements.length) + throw new Error('Matrix row must match row dimensions!'); + var M = matrix.clone(); + M.elements[i] = x.clone().elements; + return M; + } + + function matgetcol(matrix, col_index) { + col_index = Number(col_index); + var M = Matrix.fromArray([]); + matrix.each(function(x, i, j) { + if(j === col_index) { + M.elements.push([x.clone()]); + } + }); + return M; + } + + function matsetcol(matrix, j, col) { + j = Number(j); + if(matrix.rows() !== col.elements.length) + throw new Error('Matrix columns must match number of columns!'); + col.each(function(x, i) { + matrix.set(i-1, j, x.elements[0].clone()); + }); + return matrix; + } + + function matset(matrix, i, j, value) { matrix.elements[i][j] = value; return matrix; diff --git a/spec/core.spec.js b/spec/core.spec.js index 8a46b8f1..581796f9 100644 --- a/spec/core.spec.js +++ b/spec/core.spec.js @@ -12,20 +12,29 @@ describe('Nerdamer core', function () { }; it('should handle errors', function () { - // given - var formula1 = '0/0'; - var formula2 = '0^0'; - var formula3 = '-Infinity+Infinity'; - - // when / then - expect(function () { nerdamer(formula1) }).toThrowError(); - expect(function () { nerdamer(formula2) }).toThrowError(); - expect(function () { nerdamer(formula3) }).toThrowError(); + var formulas = [ + '0/0', + '0^0', + '-Infinity+Infinity', + 'Infinity/Infinity', + 'Infinity^Infinity', + '1^Infinity', + 'Infinity^0', + '(-Infinity)^0', + 'Infinity*0' + ]; + + for(var i=0; i