I was learning JavaScript by completing challenges on CoderByte[0], where one of the hard challenges was to find the point where two lines intersect. The lines were defined by two sets of points, and you had to return your answers as rationals, not floats. The challenge isn't timed, so I got a little carried away: ended up making a Fraction class, Equation class, etc. This first iteration could only solve linear equations, but I decided to expand it out into a library that could solve higher order polynomials and manipulate expressions.
On a related note, solving cubics is actually kind of hard. This guy Cardano[1] figured it out[2] in the 1500s, but his solution was incomplete because he wasn't aware of imaginary numbers at the time. I then found you could solve cubics with some trig[3] and decided to go that route. Anyway, hope you enjoy, and of course I am interested in your feedback.
Cardanos equation is complete, but only under the assumption that complex numbers exist, however, the same is true for the formula of closed-form solutions of quadratic equations. The difference is that Cardanos equation might make use of complex numbers but in the end, returns a real solution whereas the quadratic solver remains complex whenever D < 0.
So in order to implement qubic equations you'd need (a) support for complex numbers, even though the final solution might be real and (b) support for reducing (square and higher order) roots. (b) would be a very valuable addition, as it also allows you to incorporate equations like x^2 - 2 = 0 which solves to x = sqrt(2) or x = -sqrt(2).
Yes, thank you for the clarification. Maybe "incomplete" was the wrong word; I was referring to the note on the Wikipedia page:
> At this point, Cardano, who did not know complex numbers, supposed that the roots of this equation were real, that is that q^2/4 + p^3/27 > 0.
I actually had initial plans to do it Cardano's way: I added a Complex class for the very situation you described[0], but ended up abandoning it as the trig solution seemed more straightforward.
This is so well done! There are so many little touches here that delights me like the keyboard shortcuts for jumping right in and the LaTeX support. Even though this started off as a learning project for you, know that this is probably better than 95% of the API documentation I read from more professional development teams.
Jason Long's Cayman Theme was unfamiliar to me until I saw your citation. Kudos to your good taste.
Documentation is pretty good. It probably skews more towards developers with experience using other libraries, but I think that's fine for a first version. If you want to kick it up some more, I'd love to see more practical examples that might inspire me to use it out in the wild. Also, it took me awhile to figure out what to do with the keyboard shortcut. Something more explicit or even a small screencast would be nice.
I see that you also work on the RNeo4j library, which looks super cool. Queueing that up in the future to play with...since R is a much better place for me to feed that graphing library data. Thank you so much for sharing this!
Thank you for the kind words! I appreciate it. I agree that I should add a bit more instruction for opening up the JS console in Chrome or FF. I'll also add a use case section to show some practical examples.
Glad to hear you're interested in RNeo4j; let me know what you think.
For the less dev tools savvy, you could leave those top instructions on solving 2x - 3 = 4 in a console.log in your code. So once they get dev tools open they see some more instructions for the next step.
console.log("Type the following in this order pressing enter each time you see a semi-colon: \n var expr = new Expression('x'); \n expr = expr.subtract(3); \n expr = expr.add('x'); \n console.log(expr.toString()); \n var eq = new Equation(expr, 4); \n console.log(eq.toString()); var x = eq.solveFor('x'); \n console.log('x = '' + x.toString());");
This seems like a good start towards a symbolic math library like SymPy[0] for JavaScript. There's lots of cool client-side applications for such a library, something like Mathway[1] or WolframAlpha[2] that doesn't need to hit a server to do the symbolic computation.
The algorithm I use in 'EliminateVariables' is pretty ad-hoc and has built up as I throw more situations at it.
If you want to look up how the big time guys do it, I believe Mathematica's 'Reduce' performs full on quantifier elimination via cylindrical algebraic decomposition. There aren't many open-source implementations of CAD that I know of besides the venerable C-based QEPCAD.
this looks really neat and it must have been a lot of fun to build!
it's not a feature request because I don't have a use case for this quite yet, but how complex would it be to parse a string that contains a formula? for example, it seems useful to be able to load equations by just sending the string "2x - 3 = 4" to a function.
that sounds like a fun problem to solve as well. maybe useful to the library too. just a thought! great work on this library and thanks for publishing.
Thanks! Fun was the main motivation for this project.
Parsing strings into expressions is something that math.js offers currently with math.parse and expression trees[0]; I was discussing it with the author the other day[1].
I also created an algebra npm package, it implements what I learned at Algebra first year course at Università Degli Studi di Genova: http://g14n.info/algebra/
Actually your lib seems more an equation parser, not related to linear algebra, field and group theory and other algebra classic topics.
By the way, do you see any intersection or chance of cooperation between both libs?
There are powerful tools out there that can do this type of computation and more in a breeze. I have personally worked on SaturnAPI [0], which is a RESTful API for Matlab/Octave. You can build your own APIs to do almost any calculation imaginable. If anyone needs to solve equations, definitely give it a shot. You can solve all sorts of equations, linear and non-linear [1].
the API is really clear and aesthetic. the whole work seems self contained. it is just awesome. im excited to think about an addition for matrices and combinatorics and calculus as well. this deserves to become like a Magma for js. unlike quite a lot of Shown HN this already seems complete, even the documentation, so aside from hoping it expands I feel there isnt much missing to point out. maybe a calculator graphical interface to produce expressions? oh and defnitely big num support!
At one point I did have an interactive example on the project page where you could manipulate an expression with a calculator-looking number pad, but after I ran it by a few friends they seemed mostly confused by its functionality so I removed it.
I definitely want to expand the library's functionality; this project has been my go-to for when I'm burnt out on other projects so I don't plan on putting it down anytime soon. Some basic calculus seems like a natural next step, though that might betray the name algebra.js. :)
Yeah, it could be used like that. The main use case that kept coming to mind while I was writing it is interactive tutorials. You could easily build an interactive "what happens when you multiply this expression by [some user input]" type of thing.
Quintic equations cannot be solved algebraically in the general case. It would require more understanding of algebra by the program whereas I suspect this merely detects the order of the equation and then applies the proper solving formula (Abc for 2nd, Cardano for 3rd).
But nice work, it looks really professional for an out of hand learning project!
I was learning JavaScript by completing challenges on CoderByte[0], where one of the hard challenges was to find the point where two lines intersect. The lines were defined by two sets of points, and you had to return your answers as rationals, not floats. The challenge isn't timed, so I got a little carried away: ended up making a Fraction class, Equation class, etc. This first iteration could only solve linear equations, but I decided to expand it out into a library that could solve higher order polynomials and manipulate expressions.
On a related note, solving cubics is actually kind of hard. This guy Cardano[1] figured it out[2] in the 1500s, but his solution was incomplete because he wasn't aware of imaginary numbers at the time. I then found you could solve cubics with some trig[3] and decided to go that route. Anyway, hope you enjoy, and of course I am interested in your feedback.
[0] http://coderbyte.com/
[1] https://en.wikipedia.org/wiki/Gerolamo_Cardano
[2] https://en.wikipedia.org/wiki/Cubic_function#Cardano.27s_met...
[3] http://www.nickalls.org/dick/papers/maths/cubic1993.pdf