Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nerdamer

Package Overview
Dependencies
Maintainers
2
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nerdamer - npm Package Compare versions

Comparing version 1.0.4 to 1.1.0

1

all.js

@@ -17,1 +17,2 @@ /*

module.exports = nerdamer;

2

package.json

@@ -9,3 +9,3 @@ {

"license": "MIT",
"version": "1.0.4",
"version": "1.1.0",
"homepage": "http://nerdamer.com/",

@@ -12,0 +12,0 @@ "directory": {

@@ -0,1 +1,3 @@

[![Build Status](https://travis-ci.org/jiggzson/nerdamer.svg?branch=master)](https://travis-ci.org/jiggzson/nerdamer)
Nerdamer

@@ -2,0 +4,0 @@ ========

@@ -34,2 +34,4 @@ /*

FN = core.groups.FN,
Settings = core.Settings,
range = core.Utils.range,
isArray = core.Utils.isArray;

@@ -56,3 +58,13 @@

core.Settings.NON_LINEAR_START = 0.01;
//When points are generated as starting points for Newton's method, they are sliced into small
//slices to make sure that we have convergence on the right point. This defines the
//size of the slice
core.Settings.NEWTON_SLICES = 200;
//The epsilon used in Newton's iteration
core.Settings.NEWTON_EPSILON = Number.EPSILON*2;
//The distance in which two solutions are deemed the same
core.Settings.SOLUTION_PROXIMITY = 1e-14;
//Indicate wheter to filter the solutions are not
core.Settings.FILTER_SOLUTIONS = true;
core.Symbol.prototype.hasTrig = function () {

@@ -95,3 +107,5 @@ return this.containsFunction(['cos', 'sin', 'tan', 'cot', 'csc', 'sec']);

var eqn = this.removeDenom();
return _.expand(_.subtract(eqn.LHS, eqn.RHS));;
var _t = _.subtract(eqn.LHS, eqn.RHS);
var retval = _.expand(_t);
return retval;
},

@@ -169,3 +183,22 @@ removeDenom: function () {

core.Expression.prototype.solveFor = function (x) {
return solve(core.Utils.isSymbol(this.symbol) ? this.symbol : this.symbol.toLHS(), x).map(function (x) {
var symbol;
if(this.symbol instanceof Equation) {
//exit right away if we already have the answer
//check the LHS
if(this.symbol.LHS.isConstant() && this.symbol.RHS.equals(x))
return new core.Expression(this.symbol.LHS);
//check the RHS
if(this.symbol.RHS.isConstant() && this.symbol.LHS.equals(x))
return new core.Expression(this.symbol.RHS);
//otherwise just bring it to LHS
symbol = this.symbol.toLHS();
}
else {
symbol = this.symbol;
}
return solve(symbol, x).map(function (x) {
return new core.Expression(x);

@@ -546,4 +579,4 @@ });

quad: function (c, b, a) {
var bsqmin4ac = _.subtract(_.pow(b.clone(), Symbol(2)), _.multiply(_.multiply(a.clone(), c.clone()), Symbol(4)))/*b^2 - 4ac*/;
var det = _.pow(bsqmin4ac, Symbol(0.5));
var discriminant = _.subtract(_.pow(b.clone(), Symbol(2)), _.multiply(_.multiply(a.clone(), c.clone()), Symbol(4)))/*b^2 - 4ac*/;
var det = _.pow(discriminant, Symbol(0.5));
var retval = [

@@ -693,11 +726,14 @@ _.parse(_.divide(_.add(b.clone().negate(), det.clone()), _.multiply(new Symbol(2), a.clone()))),

* @param {Number} step
* @param {Array} points
* @returns {Array}
*/
getPoints: function (symbol, step) {
getPoints: function (symbol, step, points) {
step = step || 0.01;
points = points || [];
var f = build(symbol);
var start = Math.round(f(0)),
var x0 = 0;
var start = Math.round(x0),
last = f(start),
last_sign = last / Math.abs(last),
points = [],
rside = core.Settings.ROOTS_PER_SIDE, // the max number of roots on right side

@@ -711,32 +747,34 @@ lside = rside * 2 + 1; // the max number of roots on left side

symbol.each(function (x) {
if (x.containsFunction('log'))
if (x.containsFunction(core.Settings.LOG))
points.push(0.1);
});
// Possible issue #1. If the step size exceeds the zeros then they'll be missed. Consider the case
// where the function dips to negative and then back the positive with a step size of 0.1. The function
// will miss the zeros because it will jump right over it. Think of a case where this can happen.
for (var i = start; (i) < core.Settings.SOLVE_RADIUS; i++) {
var val = f(i * step),
sign = val / Math.abs(val);
if (isNaN(val) || !isFinite(val) || points.length > rside) {
break;
var left = range(-core.Settings.SOLVE_RADIUS, start, step),
right = range(start, core.Settings.SOLVE_RADIUS, step);
var test_side = function(side, num_roots) {
var xi, val, sign;
var hits = [];
for(var i=0, l=side.length; i<l; i++) {
xi = side[i]; //the point being evaluated
val = f(xi);
sign = val / Math.abs(val);
//Don't add non-numeric values
if (isNaN(val) || !isFinite(val) || hits.length > num_roots) {
continue;
}
//compare the signs. The have to be different if they cross a zero
if (sign !== last_sign) {
hits.push(xi); //take note of the possible zero location
}
last_sign = sign;
}
//compare the signs. The have to be different if they cross a zero
if (sign !== last_sign) {
points.push((i - 1) / 2); //take note of the possible zero location
}
last_sign = sign;
}
//check the other side
for (var i = start - 1; i > -core.Settings.SOLVE_RADIUS; i--) {
var val = f(i),
sign = val / Math.abs(val);
if (isNaN(val) || !isFinite(val) || points.length > lside)
break;
//compare the signs. The have to be different if they cross a zero
if (sign !== last_sign)
points.push((i - 1) / 2); //take note of the possible zero location
last_sign = sign;
}
points = points.concat(hits);
};
test_side(left, lside);
test_side(right, rside);
return points;

@@ -756,2 +794,3 @@ },

}
iter++;

@@ -765,5 +804,7 @@ if (iter > maxiter)

}
while (e > Number.EPSILON)
return x;
while (e > Settings.NEWTON_EPSILON)
//check if the number is indeed zero. 1e-13 seems to give the most accurate results
if(Math.abs(f(x)) <= 1e-13)
return x;
},

@@ -895,3 +936,2 @@ rewrite: function (rhs, lhs, for_variable) {

var solve = function (eqns, solve_for, solutions) {
//make preparations if it's an Equation

@@ -982,2 +1022,4 @@ if (eqns instanceof Equation) {

numvars = vars.length;//how many variables are we dealing with
//if we're dealing with a single variable then we first check if it's a

@@ -1186,10 +1228,16 @@ //polynomial (including rationals).If it is then we use the Jenkins-Traubb algorithm.

var points3 = __.getPoints(eq, 0.01);
var points = core.Utils.arrayUnique(points1.concat(points2).concat(points3)),
l = points.length;
var points = core.Utils.arrayUnique(points1.concat(points2).concat(points3)).sort(function(a, b) { return a-b});
//generate slices
//points = core.Utils.arrayAddSlices(points, Settings.NEWTON_SLICES);
//compile the function and the derivative of the function
var f = build(eq.clone());
var d = _C.diff(eq.clone());
var fp = build(d);
for (var i = 0; i < l; i++) {
for (var i = 0; i < points.length; i++) {
var point = points[i];
add_to_result(__.Newton(point, f, fp), has_trig);

@@ -1200,3 +1248,3 @@ }

catch(e) {
;
console.log(e);
}

@@ -1210,37 +1258,47 @@ }

try {
var coeffs = core.Utils.getCoeffs(eq, solve_for);
var factored = core.Algebra.Factor.factor(eq.clone());
if(factored.group === CB) {
factored.each(function(x) {
add_to_result(solve(x, solve_for));
});
}
else {
var coeffs = core.Utils.getCoeffs(eq, solve_for);
var l = coeffs.length,
deg = l - 1; //the degree of the polynomial
//get the denominator and make sure it doesn't have x
var l = coeffs.length,
deg = l - 1; //the degree of the polynomial
//get the denominator and make sure it doesn't have x
//handle the problem based on the degree
switch (deg) {
case 0:
var separated = separate(eq);
var lhs = separated[0],
rhs = separated[1];
if (lhs.group === core.groups.EX) {
add_to_result(_.parse(core.Utils.format(core.Settings.LOG+'(({0})/({2}))/'+core.Settings.LOG+'({1})', rhs, lhs.value, lhs.multiplier)));
}
break;
case 1:
//nothing to do but to return the quotient of the constant and the LT
//e.g. 2*x-1
add_to_result(_.divide(coeffs[0], coeffs[1].negate()));
break;
case 2:
add_to_result(__.quad.apply(undefined, coeffs));
break;
case 3:
add_to_result(__.cubic.apply(undefined, coeffs));
break;
case 4:
add_to_result(__.quartic.apply(undefined, coeffs));
break;
default:
add_to_result(__.csolve(eq, solve_for));
if (solutions.length === 0)
add_to_result(__.divideAndConquer(eq, solve_for));
}
}
//handle the problem based on the degree
switch (deg) {
case 0:
var separated = separate(eq);
var lhs = separated[0],
rhs = separated[1];
if (lhs.group === core.groups.EX) {
add_to_result(_.parse(core.Utils.format('log(({0})/({2}))/log({1})', rhs, lhs.value, lhs.multiplier)));
}
break;
case 1:
//nothing to do but to return the quotient of the constant and the LT
//e.g. 2*x-1
add_to_result(_.divide(coeffs[0], coeffs[1].negate()));
break;
case 2:
add_to_result(__.quad.apply(undefined, coeffs));
break;
case 3:
add_to_result(__.cubic.apply(undefined, coeffs));
break;
case 4:
add_to_result(__.quartic.apply(undefined, coeffs));
break;
default:
add_to_result(__.csolve(eq, solve_for));
if (solutions.length === 0)
add_to_result(__.divideAndConquer(eq, solve_for));
}
}

@@ -1272,3 +1330,3 @@ catch (e) { /*something went wrong. EXITING*/

}
else if(lhs.fname === 'log') {
else if(lhs.fname === core.Settings.LOG) {
//ax+b comes back as [a, x, ax, b];

@@ -1328,3 +1386,3 @@ var parts = explode(lhs.args[0], solve_for);

}
return solutions;

@@ -1376,2 +1434,2 @@ };

nerdamer.api();
})();
})();

@@ -396,3 +396,3 @@ /* global expect */

// then
expect(result).toBe('(1+2*x)^2*(1/4)');
expect(result).toBe('(1/4)*(1+2*x)^2');
});

@@ -418,6 +418,6 @@

expected: '(1+x)^2'
},
},
{
given: 'factor(x^2-y^2)',
expected: '(-y+x)*(x+y)'
expected: '-(-x+y)*(x+y)'
},

@@ -462,7 +462,15 @@ {

given: 'factor(sqrt(4*x^2*y+4*x^2))',
expected: '(2)*(abs(x))*(sqrt(1+y))'
expected: '2*abs(x)*sqrt(1+y)'
},
{
given: 'factor(x^3-1/2x^2-13/2x-3)',
expected: '(-3+x)*(1+2*x)*(1/2)*(2+x)'
expected: '(1/2)*(-3+x)*(1+2*x)*(2+x)'
},
{
given: 'factor(x^16-1)',
expected: '(-1+x)*(1+x)*(1+x^2)*(1+x^4)*(1+x^8)'
},
{
given: 'factor(-1866240-311040*x^2-3265920*x+1120*x^8+150080*x^6+17610*x^7+2026080*x^4+2509920*x^3+30*x^9+738360*x^5)',
expected: '10*(-1+x)*(1+x)*(3*x+4)*(6+x)^6'
}

@@ -480,2 +488,7 @@ ];

it('should not have any regression to factor', function() {
//this test will absolutely break as factor improves enough to factor this expression. For now it just serves as a safeguard
expect(nerdamer('factor(x^a+2x^(a-1)+1x^(a-2))').toString()).toEqual('2*x^(-1+a)+x^(-2+a)+x^a');
});
it('should correctly determine the polynomial degree', function () {

@@ -702,3 +715,3 @@ // given

given: 'simplify(cos(x)^2+sin(x)^2+cos(x)-tan(x)-1+sin(x^2)^2+cos(x^2)^2)',
expected: '-(-1-cos(x)+tan(x))'
expected: '-tan(x)+1+cos(x)'
},

@@ -733,2 +746,6 @@ {

expected: '(29/53)*i+22/53'
},
{
given: 'simplify(((17/2)*(-5*K+32)^(-1)*K^2+(5/2)*K-125*(-5*K+32)^(-1)*K-16+400*(-5*K+32)^(-1))*(-17*(-5*K+32)^(-1)*K+80*(-5*K+32)^(-1))^(-1))',
expected: '-(-112-4*K^2+35*K)*(-80+17*K)^(-1)'
}

@@ -735,0 +752,0 @@ ];

@@ -54,2 +54,3 @@ /* global expect */

it('should respect modulus with percentages', function(){expect(parse('8000%%8')).toEqual(0);});
it('should correctly handle modulus left assoc', function(){expect(parse('3*3%9')).toEqual(0);});
});

@@ -125,2 +126,8 @@

describe('Setting vector values', function() {
it('should set values of vectors with the assign operator', function() {
expect(parse('[1,2][1]:x').toString()).toEqual('[1,x]');
});
});
describe('Substitutions', function(){

@@ -127,0 +134,0 @@ it('should substitute x', function() {expect(parse('x+1', {x: 4})).toEqual(5);});

@@ -53,3 +53,3 @@ /* global expect */

TeX: '\\frac{3 \\cdot x^{\\frac{2}{3}}}{4}',
decimalTeX: '0.75 \\cdot x^{0.666666666666666666666666666666666666667}'
decimalTeX: '0.75 \\cdot x^{0.6666666666666666666666666666666666666666666666666666666666666666666666666666667}'
}, {

@@ -56,0 +56,0 @@ given: '4*cos(x)',

@@ -78,2 +78,3 @@ /* global expect */

{
//NOTE: this test has duplicates
given: 'solve(sqrt(x^3)+sqrt(x^2)-sqrt(x)=0,x)',

@@ -92,3 +93,3 @@ expected: '[0,78202389238903801/240831735646702201]'

given: 'solve(x=2/(3-x),x)',
expected: '[1,2]'
expected: '[2,1]'
},

@@ -114,2 +115,4 @@ {

},
//The tests below were disabled. Too verbose.
/*
{

@@ -122,2 +125,3 @@ given: 'solve(cos(x), x)',

},
{

@@ -131,2 +135,3 @@ given: 'solve(cos(x)*x+1-cos(x), x)',

},
*/
{

@@ -147,2 +152,4 @@ given: 'solve(a*x^3+b*x+c, x)',

},
//The tests below are incorrect and have no solutions
/*
{

@@ -156,2 +163,3 @@ given: 'solve(log(x,2)+log(x,3)=log(x,5), x)',

},
*/
{

@@ -187,4 +195,5 @@ given: 'solve((1/2)*sqrt(-4*x+4*y)-2+y, y)',

//NOTE: 4503599627370497/4503599627370496 result can be safely removed since it has rounding errors
//NOTE: this test has duplicate solutions. The last two are duplicates of the first but have rounding errors
given: 'solve(sqrt(x)-2x+x^2,x)',
expected: '[(1/2)*(-sqrt(5)+3),0,1,4503599627370497/4503599627370496]'
expected: '[(1/2)*(-sqrt(5)+3),0,1,832040/2178309]'
},

@@ -269,5 +278,14 @@ {

it('parse equations correctly', function () {
it('should parse equations correctly', function () {
expect(nerdamer("-(a+1)=(a+3)^2").toString()).toEqual('-1-a=(3+a)^2');
});
//NOTE: contains duplicates
it('should solve functions with factorials', function() {
expect(nerdamer('solve(x!-x^2,x)').text()).toEqual('[-2.2003917826105948,-4.010232827899529,-2.938361683501947,1,1.0000000000000009,1.0000000000000007,3.5623822853908957,3.5623822853908966,0.9999999999999998,1.0000000000000002]');
});
xit('should solve factors', function() {
expect(nerdamer('solve((x-1)*(-a*c-a*x+c*x+x^2),x)').text()).toEqual('[1,-c,a]');
});
});

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc