jiggzson / nerdamer

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

Function roots of a number #548

Closed FilipeAC closed 4 years ago

FilipeAC commented 4 years ago

I looked into previous issues about the roots command, but I couldn't find if this is an issue or the expected behavior:

roots(5) --> +sqrt(5), -sqrt(5)

The command roots was supposed to return the square root of a single number when no expression is given?

jiggzson commented 4 years ago

@FilipeAC, I'm still a little confused. Can you explain it a bit?

FilipeAC commented 4 years ago

My code is interpreting an array of numbers as a polynomial equals to zero, something like this:

[5,1,3,] --> 5x^2 + 1x + 3 = 0

So, just a number would mean

[3] -- > 3 = 0

which is clearly a false statement. So I was expecting some error or NaN or something like that from "roots(3)", since there are no values for variable x that makes 3 = 0 a true statement. That's how I was interpreting the "roots" function. Matlab, for example, returns an empty value for "roots(3)".

But Nerdamer returns -sqrt(3) and +sqrt(3) for "roots(3)", that's when I got confused.

Later, I realized Wolfram Alpha behaves like this so I guess it for compatibility reasons, wright?

jiggzson commented 4 years ago

I see. You're looking for the real roots. Personally I'm not too fond of the roots function. It needs a serious overhaul IMO. I would use solve instead. You can also filter out imaginary results with the snippet below.

var realRoots = function() {
    return nerdamer.solve.apply(null, arguments).symbol.elements.filter(function(solution) {
        return !solution.isImaginary();
    });
};

The biggest issue I see is that your solutions will be of nerdamer's Symbol class so you'd probably want to convert those.

var realRoots = function() {
    return nerdamer.solve.apply(null, arguments).symbol.elements.filter(function(solution) {
        return !solution.isImaginary();
    }).map(function(x) { return nerdamer(x); });
};

console.log(realRoots('5', 'x')); //[]
console.log(realRoots('5x^3 + 1x + 3', 'x')); //[ { symbol:{ group: 1, value: '#', multiplier: [Object], power: [Object] } } ]
console.log(realRoots('5x^2 + 1x + 3', 'x')); //[]

Later, I realized Wolfram Alpha behaves like this so I guess it for compatibility reasons, wright?

No. I don't really adhere to any compatibility with Wolfram Alpha. If anything, I maintain a closer compatibility to Maxima but even that's somewhat loosely. Let me know if that helps and please close this issue out if it does.

FilipeAC commented 4 years ago

Actually, for me, it's easier to implement an IF and don't call the "roots" function when I have just a number. I just opened this issue because I really appreciate the Nerdamer project and I'd like to let you know if it was a some sort of bug.

FilipeAC commented 4 years ago

Thank you again!