jiggzson / nerdamer

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

Pending issues with solve #322

Open Happypig375 opened 6 years ago

Happypig375 commented 6 years ago

~``` solve((x-1)(x+1)x=3x,x) => [(-1/3)(-1)^(1/6)24^(1/3)sqrt(3)^(1/3)-4(-1)^(-1/6)24^(-1/3)sqrt(3)^(-1/3), (1/6)(-1)^(1/6)(1+isqrt(3))24^(1/3)sqrt(3)^(1/3)+2((-1)^(1/6)24^(1/3)sqrt(3)^(1/3))^(-1)(-isqrt(3)+1), (1/6)(-1)^(1/6)(-isqrt(3)+1)24^(1/3)sqrt(3)^(1/3)+2((-1)^(1/6)24^(1/3)sqrt(3)^(1/3))^(-1)(1+isqrt(3))] should=> [2,-2,0]~

Fixed. Adding test.

Happypig375 commented 6 years ago

~solve(sqrt(x)+sqrt(2x+1)=5,x) => []~ should=> [4]

jiggzson commented 6 years ago

@Happypig375 Thanks. Can you start closing off some of the issues that are fixed?

Happypig375 commented 6 years ago

~solve(x=2/(3-x),x)~ => [1,1.0000000000000002] (@0.7.13) => [2*(-x+3)^(-1)] (@0.7.14) should=> [1,2]

Happypig375 commented 6 years ago

solveEquations([sqrt(2)a-sqrt(2)c+b+d=0,a+c+sqrt(2)b-sqrt(2)d=0,a+c=0,b+d=1]) => Error: System must contain all linear equations!

All four equations are linear, but multivariate.

jiggzson commented 6 years ago

@Happypig375 so which variable are you trying to solve for?

Happypig375 commented 6 years ago

@jiggzson All of them. Currently solveEquations([a+b=1,a-b=2]) => [a,1.5,b,-0.5]. Therefore, solveEquations([sqrt(2)a-sqrt(2)c+b+d=0,a+c+sqrt(2)b-sqrt(2)d=0,a+c=0,b+d=1]) should=> [a,-1/(2 sqrt(2)), b, 1/2, c, 1/(2 sqrt(2)), d, 1/2]

Happypig375 commented 6 years ago

Also, I think that solveEquations([a+b=1,a-b=2]) should=> [a=1.5,b=-0.5] This is more clear about the connection between the unknown and the value.

jiggzson commented 6 years ago

Oops. I confused it with solve for a moment. You're right. Something is causing it to incorrectly flag it as non-linear. I'll look into this.

Happypig375 commented 6 years ago

~solve(sqrt(x)-1,x) => [] should=> [1]~ ~solve(sqrt(x)+1,x) => [0] should=> []~

Happypig375 commented 6 years ago

~solve(sqrt(x^2+1),x) => [] should=> [i, -i] solve(sqrt(x^2-1),x) => [] should=> [1, -1]~

Happypig375 commented 6 years ago

The second argument to solve (variable to solve for) should be inferred for univariate polynomials/equations, and solve for all variables in multivariate equations like in solveEquations.

Happypig375 commented 6 years ago

Cross-ref: #345

jiggzson commented 6 years ago

~~*solve(((x+1)((x+1)+1))/2=n,x)** Expected: +/-(sqrt(8n+1)+3)/2 Gives: +/-(sqrt(4n+1)+3)/2~~ Fixed!

Happypig375 commented 6 years ago

solve(x^x^x^2018=2018,x) => [] should=> [2018^(1/2018)]

See https://youtu.be/UNwhaN2s2ww

Happypig375 commented 6 years ago

~solve(sqrt(10x+186)=x+9,x) => [7.000000000000002,7,6.999999999999999] should=> [7]~

Happypig375 commented 6 years ago

~solve(x^3+8=x^2+6,x) eval=> [−0.9999999999999996,0.9999999999999999⋅i+1,−0.9999999999999999⋅i+1] should=> [-1,1+i,1-i]~

Happypig375 commented 6 years ago

Also, the solve function itself looks like the variable x is assumed when the 2nd argument is not provided.

  1. The minimum number of arguments needed to pass to solve should be 1 instead of 2.
  2. If the equation given is in one unknown, then that unknown should be assumed the variable to solve, and return to using x if there are multiple variables (or throw).
Happypig375 commented 6 years ago

Missing active label here 😃

jiggzson commented 6 years ago

The minimum number of arguments needed to pass to solve should be 1 instead of 2.

I'll fix this. Additionally I've extended the symbolic range of Solve but solve is in dire need of unit tests.

jiggzson commented 6 years ago

@Happypig375, automatically assuming the variable won't work at the moment since solve is used for various cases including systems of equations. I'm planning to refactor Solve in the near future so I'll go ahead and take care of it then.

Happypig375 commented 6 years ago

Absolutely wrong answer by solve: ~solve(x^3-10x^2+31x-30,x)~ should return [2,3,5]

jiggzson commented 6 years ago

Absolutely wrong answer by solve:

Have you verified the answer? The result you get is: A. Ugly B. Needlessly complex C. 100% correct The problem is that nerdamer does not simplify complex numbers efficiently and that is something I'm currently working on. If I solve it numerically I get the right answer right away. Would defaulting to that solve your problem? The downside is that you don't get nice algebraic answers anymore whenever possible.

Happypig375 commented 6 years ago

Have you verified the answer? The result you get is: A. Ugly B. Needlessly complex C. 100% correct

A. Evaluate can't simplify it B. The length exceeds Wolfram Alpha's input limit

How can I verify the answer when I don't even know what to do with it?

If I solve it numerically I get the right answer right away.

Ok

Would defaulting to that solve your problem? The downside is that you don't get nice algebraic answers anymore whenever possible.

Just fix this but don't change the defaults.

jiggzson commented 6 years ago

@Happypig375, fixing this is a little more involved than it might appear. One might be tempted to solve this numerically but then you end up with a tiny imaginary part for all the answers which is not ideal. Not to mention that the real part will now have rounding errors. Until I can successfully simplify [(-1/3)*(-20+18*i*sqrt(3))^(1/3)*2^(-1/3)+(-7/3)*(-20+18*i*sqrt(3))^(-1/3)*2^(1/3)+10/3,(1/6)*(-20+18*i*sqrt(3))^(1/3)*(1+i*sqrt(3))*2^(-1/3)+(7/6)*((-20+18*i*sqrt(3))^(1/3)*2^(-1/3))^(-1)*(-i*sqrt(3)+1)+10/3,(1/6)*(-20+18*i*sqrt(3))^(1/3)*(-i*sqrt(3)+1)*2^(-1/3)+(7/6)*((-20+18*i*sqrt(3))^(1/3)*2^(-1/3))^(-1)*(1+i*sqrt(3))+10/3] algebraically, I've decided to take the following approach.

The unfortunate part is that I now solve twice but that'll have to do until I find the time to simplify the algebraic solution above.

Happypig375 commented 6 years ago

I think that this can easily solved by implementing cube root for complex numbers. Ideas?

jiggzson commented 6 years ago

I think that this can easily solved by implementing cube root for complex numbers. Ideas?

That's what I initially thought myself. I implemented nth root for complex numbers which might still need some final touch-ups but when doing this one of the roots becomes 0.000000000000000221377340243793938154443⋅i+1.999999999999999555910790149937482438160. This has rounding errors in both the real and imaginary part. I can solve this algebraically at which point this error goes away but that requires a bit more work. I eventually hope to get to that at some point but I won't have the time now.

Happypig375 commented 6 years ago

I think I saw where the rounding error comes from - using Math.sin and Math.cos inside Parser.pow. The conversion between Frac and Javascript Number is what causes the error.

jiggzson commented 6 years ago

The conversion between Frac and Javascript Number is what causes the error.

I think that exacerbates the problem but doesn't eliminate it from what I remember. I'll give it a go later so let's see. Additionally, I still need to work on eliminating rounding errors in pow.

Happypig375 commented 6 years ago

The workaround earlier is not useful when fractional answers are there... ~solve(8x^3-26x^2+3x+9,x) should=> [3,3/4,-1/2] It currently produces [(-1/24)*(-13984+15120*i*sqrt(3))^(1/3)*2^(-1/3)+(-151/6)*(-13984+15120*i*sqrt(3))^(-1/3)*2^(1/3)+13/12,(1/48)*(-13984+15120*i*sqrt(3))^(1/3)*(1+i*sqrt(3))*2^(-1/3)+(151/12)*((-13984+15120*i*sqrt(3))^(1/3)*2^(-1/3))^(-1)*(-i*sqrt(3)+1)+13/12,(1/48)*(-13984+15120*i*sqrt(3))^(1/3)*(-i*sqrt(3)+1)*2^(-1/3)+(151/12)*((-13984+15120*i*sqrt(3))^(1/3)*2^(-1/3))^(-1)*(1+i*sqrt(3))+13/12].~

Another bug is present here. When evaluate is checked, the vector does not evaluate automatically, but evaluates when vecget one of the solutions. Aka solve(8x^3-26x^2+3x+9,x) eval=> [(-1/24)*(-13984+15120*i*sqrt(3))^(1/3)*2^(-1/3)+(-151/6)*(-13984+15120*i*sqrt(3))^(-1/3)*2^(1/3)+13/12,(1/48)*(-13984+15120*i*sqrt(3))^(1/3)*(1+i*sqrt(3))*2^(-1/3)+(151/12)*((-13984+15120*i*sqrt(3))^(1/3)*2^(-1/3))^(-1)*(-i*sqrt(3)+1)+13/12,(1/48)*(-13984+15120*i*sqrt(3))^(1/3)*(-i*sqrt(3)+1)*2^(-1/3)+(151/12)*((-13984+15120*i*sqrt(3))^(1/3)*2^(-1/3))^(-1)*(1+i*sqrt(3))+13/12]

vecget(solve(8x^3-26x^2+3x+9,x),0) eval=> 1.0515041619631423e+33/754813980813027500i-300239975158033/150119987579016

Really. The rounding errors are important to fix.

Happypig375 commented 6 years ago

Also this. ~solve(x^3-1/2x^2-13/2x-3,x) => [(-1/3)*((315/4)*i*sqrt(3)-221/2)^(1/3)*2^(-1/3)+(-79/12)*((315/4)*i*sqrt(3)-221/2)^(-1/3)*2^(1/3)+1/6,(1/6)*((315/4)*i*sqrt(3)-221/2)^(1/3)*(1+i*sqrt(3))*2^(-1/3)+(79/24)*(((315/4)*i*sqrt(3)-221/2)^(1/3)*2^(-1/3))^(-1)*(-i*sqrt(3)+1)+1/6,(1/6)*((315/4)*i*sqrt(3)-221/2)^(1/3)*(-i*sqrt(3)+1)*2^(-1/3)+(79/24)*(((315/4)*i*sqrt(3)-221/2)^(1/3)*2^(-1/3))^(-1)*(1+i*sqrt(3))+1/6] should=> [-1/2,3,-2]~

Happypig375 commented 6 years ago

And the quartic equations solve(sqrt(sqrt(x))+sqrt(sqrt(881-x))=9,x) => [159.165753255588098206102369881636862489634] can=>[7442 - 2916 881^(1/4) + 486 sqrt(881) - 36 881^(3/4)]

Happypig375 commented 6 years ago

Where did solving in terms of other variables go? solve(sqrt(x^2-p)+2sqrt(x^2-1),x) => [] should=> [sqrt(4 - p)/sqrt(3),-sqrt(4 - p)/sqrt(3)]

jiggzson commented 6 years ago

Hmmm.... I'll take a look it.

Happypig375 commented 6 years ago

solve(x^(2i)=-x,x) => [] It should have two numerical solutions according to Wolfram Alpha.

Happypig375 commented 6 years ago

solve(x*log(x),x) => [1,0] 0 is not valid since 0*log(0) is 0*-Infinity which is undefined.

Happypig375 commented 6 years ago

~solve(x^2=x^-2,x) => [1,e^((1/2)*i*pi),e^(i*pi),e^((3/2)*i*pi)] => [1,i,-1,i]~

I have to re-enter the first output to simplify the answer. It can be simplified in one go.

jiggzson commented 6 years ago

@Happypig375, why is this a problem?

Happypig375 commented 6 years ago

solve(x^2=x^-2,x) should directly give [1,i,-1,i].

Happypig375 commented 6 years ago

Here is one where even Wolfram Alpha can't simplify: solve(-8x^3+6x-1=0,x) should=> [sin(pi/18),sin(5pi/18),sin(-7pi/18)]

See https://youtu.be/JqagcCrdpQQ

jiggzson commented 4 years ago

~solve((9x+x^2)^3+10800x+40x^4+4440x^2+720x^3+20(9*x+x^2)^2+8000,x) throws~

jiggzson commented 3 years ago

~solve((x^3-4)/(x^3+7x-11),x) does not give solutions~

jiggzson commented 3 years ago

~solve(x^3+2x^2+3x-4=0,x) gives wrong answer. Solve for cubics still broken.~

jiggzson commented 3 years ago

@Happypig375, I'm just going through the cases and marking off those that have been resolved.

Happypig375 commented 3 years ago

Nice!