
Show HN: Algebra.js – Build, display, and solve algebraic equations - nicolewhite
http://algebra.js.org/
======
nicolewhite
Hello HN,

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/](http://coderbyte.com/)

[1]
[https://en.wikipedia.org/wiki/Gerolamo_Cardano](https://en.wikipedia.org/wiki/Gerolamo_Cardano)

[2]
[https://en.wikipedia.org/wiki/Cubic_function#Cardano.27s_met...](https://en.wikipedia.org/wiki/Cubic_function#Cardano.27s_method)

[3]
[http://www.nickalls.org/dick/papers/maths/cubic1993.pdf](http://www.nickalls.org/dick/papers/maths/cubic1993.pdf)

~~~
Gladdyu
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).

~~~
nicolewhite
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.

[0]
[https://github.com/nicolewhite/algebra.js/commit/47b6cbba375...](https://github.com/nicolewhite/algebra.js/commit/47b6cbba37523da89b0228e050a9ed02e4dcb6a1)

------
kevin
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!

~~~
nicolewhite
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.

~~~
heatish
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());");
    

Very cool project by the way.

~~~
nicolewhite
That's a very clever idea. Thanks.

------
joeyrobert
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.

[0] [http://www.sympy.org/](http://www.sympy.org/)

[1] [https://mathway.com/](https://mathway.com/)

[2] [http://www.wolframalpha.com/](http://www.wolframalpha.com/)

------
dharmatech
Nice work Nicole! :-)

I work on a similar library for C# (Symbolism [1]).

Consider allowing for variable elimination in sets of equations. (See this
problem for an example:
[https://gist.github.com/dharmatech/a14d1a29a7d4c0728d37](https://gist.github.com/dharmatech/a14d1a29a7d4c0728d37))

[1]
[https://github.com/dharmatech/Symbolism/](https://github.com/dharmatech/Symbolism/)

~~~
nicolewhite
That's very cool. I should definitely add functionality for solving a system
of equations.

~~~
dharmatech
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.

PS: Big fan of your Neo4J tutorials. :-)

~~~
nicolewhite
That sounds like some fun Friday night reading. :) Glad you enjoy Neo4j!

------
davmar
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.

~~~
nicolewhite
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].

[0]
[http://mathjs.org/docs/expressions/expression_trees.html](http://mathjs.org/docs/expressions/expression_trees.html)

[1]
[https://news.ycombinator.com/item?id=10042470](https://news.ycombinator.com/item?id=10042470)

------
fibo
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/](http://g14n.info/algebra/)

~~~
nicolewhite
Yeah, I remember seeing that when I found the name algebra was already taken
on npm. :)

~~~
fibo
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?

------
artartart
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].

[0] [https://saturnapi.com/](https://saturnapi.com/)

[1] [http://www.mathworks.com/help/symbolic/equation-
solving.html](http://www.mathworks.com/help/symbolic/equation-solving.html)

------
1arity
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!

~~~
nicolewhite
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. :)

~~~
1arity
Maybe do the Alphabet thing and subsume them all under a parent project name!
A is for Algebra :)

( Whiteboard ?

A place to do math, obviously, and you did say you go to it when bored of
other projects. )

------
clebio
So it's like an early-stage CAS written in Javascript?

E.g. Sage math ([http://www.sagemath.org/](http://www.sagemath.org/))

~~~
nicolewhite
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.

------
ahmacleod
Nice work. I've built roughly half of this before, but your API is cleaner and
the docs really tie it together.

------
CaiGengYang
Hi does anyone know how to download Algebra.js ?

I clicked the "Download .min.js" tab on the Algebra.js.org page but was given
this error message :

[http://algebra.js.org/javascripts/algebra.min.js](http://algebra.js.org/javascripts/algebra.min.js)

------
1arity
it would be cool to have

    
    
      new CompoundExpression( "x^2 - xy + 5" )
    

or even

    
    
      new PolishSquarefree("+")("+")("^")("x")(2)("-xy")(5)
    

or even

    
    
      new Polish("+")("-")("^")("x")(2)(".")("x")("y")(5)

------
maxwelljoslyn
Hey, this is cool! Great work.

------
liammclennan
Great project. Please add support for quintic equations.

~~~
Gladdyu
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!

~~~
nicolewhite
> I suspect this merely detects the order of the equation and then applies the
> proper solving formula (Abc for 2nd, Cardano for 3rd).

That's exactly right. You could build a quintic equation, but attempting to
solve will return undefined.

