jiggzson / nerdamer

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

Add dependencies when building JS functions in buildFunction #481

Closed Saikedo closed 5 years ago

Saikedo commented 5 years ago

Is there a reason why the factorial for evaluating and for buildFunction differ so much?

Take a look at these examples

nerdamer("3.1!").evaluate().text() // returns "6.812622863016674" nerdamer("-3!").evaluate().text() // returns "-6"

let f = nerdamer("x!").buildFunction('x') f(3.1) // returns 6. basically it seems to use floor on argument before evaluating f(-3) // Not even defined so it throws an error.

From what I understand, evaluate of factorial uses the gamma function correct? Is there any harm to use this for buildFunction as well?

jiggzson commented 5 years ago

The factorial for fractions is calculated using the gamma function. The good news is that gamma function already exists so that part is easy. The hard part is that buildFunction doesn't pull down internal dependencies so it's not as simple as if x not int: return Math2.gamma(x). I'll repurpose this issue into something more generic, which is to add build dependencies to buildFunction

Saikedo commented 5 years ago

@jiggzson Please let me know if this is something that I can help you with. I feel like this is kinda a bit more involved and will require me to get more familiar with the library but I will be happy to help if I can. This is kind of an ugly bug for us since our graphing library just crashes when it tries to calculate a negative number of a factorial since it always expects a return value (Even if it is undefined or NaN) and does not handle the errors :)

jiggzson commented 5 years ago

Might not be that hard. I was thinking to create a list of dependencies and loop through those, then load any additional dependencies recursively. Keep in mind that if this is fixed you'll get values for all floats for the factorial function but negative integers will still throw an UndefinedError. What I'm wondering is that since this error is well-defined, why not just do a quick check for those and then replace the value with undefined? Something like

//check if negative int
value = (x%1 === 0 && x<0) ? undefined : f(x);
Saikedo commented 5 years ago

@jiggzson Why would negative integers still be undefined though? It is my understanding that they are well defined in gamma function correct?

jiggzson commented 5 years ago

Looks like they are I don't remember if nerdamer has complex infinity yet though.

Happypig375 commented 5 years ago

Nope, don't think so

jiggzson commented 5 years ago

@Happypig375, this is crazy. You comment just as I'm signing off. You're talking about complex infinity right?

jiggzson commented 5 years ago

@Happypig375, I'm not too familiar with complex infinity. I seem to recall you being somewhat familiar with it. Any suggestions on how to go about implementing this? Does its valueOf map back to JS Infinity? @Saikedo, thoughts?

Happypig375 commented 5 years ago

Complex infinity is infinity with indeterminate sign. E.g. tan(pi/2) is complex infinity.

It's valueOf shouldn't be Infinity or -Infinity because they have +/- signs. I suggest NaN.

jiggzson commented 5 years ago

Fixed.