jiggzson / nerdamer

a symbolic math expression evaluator for javascript
http://www.nerdamer.com
MIT License
514 stars 82 forks source link

solveFor return empty array #595

Closed gulyasmarton closed 3 years ago

gulyasmarton commented 3 years ago

Hello,

I have an ugly equation:

0=((2*0.87*x-2*sqrt(x^2(0.87^2-1)+4*4^2))/2)^2+((2*0.86*x-2*sqrt(x^2(0.86^2-1)+4*5^2))/2)^2-0.87*((2*0.87*x-2*sqrt(x^2(0.87^2-1)+4*4^2))/2)*((2*0.86*x-2*sqrt(x^2(0.86^2-1)+4*5^2))/2)-6^2

According to WolframAlpha the result ~ 3.9 and 13.0

The nerdamer can parse the input string without an issue (output of toString() function):

0=(-43/25)*sqrt((-651/2500)*x^2+100)*x+(-87/400)*((43/25)*x-2*sqrt((-651/2500)*x^2+100))*((87/50)*x-2*sqrt((-2431/10000)*x^2+64))+(-87/50)*sqrt((-2431/10000)*x^2+64)*x+(993/1000)*x^2+128

But when I'm trying to solve it then I got an empty array as a result without any error message...

var d = nerdamer(eqString);
console.log(d.toString());
var solutions = d.solveFor('x');
console.log(solutions);
//output: []

I do something wrong?

jiggzson commented 3 years ago

I have an ugly equation:

😆 It is a bit hairy looking but in a pet-like way.

I do something wrong?

Nope. So here's the thing. Under the hood, when all else fails, solve reverts to Newton's iterations and tries to solve it numerically. It first generates a few good starting points and then checks for zeroes around that point. In reality it should've tried something like bisection first since Newton sometimes overshoots the point because of how JS numbers behave. I've been putting it off for some time but this issue somewhat gave me a good case to work with.

This issue should be fixed on the dev branch. Let me know if you have any questions.