jiggzson / nerdamer

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

Solve issue #608

Closed markhats closed 2 years ago

markhats commented 3 years ago

Hi

I've encountered another solve issue which is closely related to: https://github.com/jiggzson/nerdamer/issues/563

Basically the following fails to give a sensible answer:

solve(x^2+a*y^2=1,y)
...
[a^(-1)*i*sqrt(-1+x^2)*sqrt(a),-a^(-1)*i*sqrt(-1+x^2)*sqrt(a)]

whereas I think it should probably be:

[sqrt(1 - x^2)/sqrt(a),sqrt(1 - x^2)/sqrt(a)] 

It seems to be the case if a is either side of y^2 and it also occurs if a is replaced with any expression (e.g. e^x). However, it works if a is replaced by a number. e.g.

solve(x^2+2*y^2=1,y)
...
[(1/4)*sqrt(-8*x^2+8),(-1/4)*sqrt(-8*x^2+8)]

Any ideas?

Thanks.

jiggzson commented 3 years ago

Basically the following fails to give a sensible answer:

I'm guessing you're referring to the fact that it appears to give a complex answer. The answer does appear to be correct. I ran a quick test. See below.

var test = function(a, x) {
    console.log(`=== testing x: ${x} & a: ${a} ===`);
    var solA = nerdamer('solve(x^2+a*y^2=1,y)');
    console.log(solA.evaluate({x: x, a:a}).text());
    var solB = nerdamer(`solve((${x})^2+${a}*y^2=1,y)`);
    console.log(solB.evaluate().text());
};

test(-1,1);
test(-10,7);
test(10,-7);
test(5,3);
test(-1,0);

// Output:
/*
=== testing x: 1 & a: -1 ===
[0,0]
[0]
=== testing x: 7 & a: -10 ===
[2.190890230020664,-2.190890230020664]
[-2.190890230020664,2.190890230020664]
=== testing x: -7 & a: 10 ===
[2.1908902300206643*i,-2.1908902300206643*i]
[2.1908902300206643*i,-2.1908902300206643*i]
=== testing x: 3 & a: 5 ===
[1.264911064067352*i,-1.264911064067352*i]
[1.2649110640673518*i,-1.2649110640673518*i]
=== testing x: 0 & a: -1 ===
[i,-i]
[-i,i]
*/

Let me know if you find otherwise. I do agree with regards the complex answer. I'll take a look to see if I can improve on situations such these.

Thanks.

markhats commented 3 years ago

Thanks for looking into this.

You are right - the result is actually technically correct and probably fine if you are just evaluating and don't care about the form of the solution. I guess I'm after a non-complex answer of a similar form to that produced if the a constant is instead a number. I'm not sure how easy that is to achieve though??

jiggzson commented 3 years ago

@markhats,

I'd prefer to not have a complex answer as well since it will create problems with buildFunction. It looks like Wolfram Alpha achieves this by factoring out sqrt(-1) and thereby cancelling the imaginary unit. I'll look into it a bit more.