Convert sympy to javascript

1,370 views
Skip to first unread message

dennis

unread,
Sep 22, 2011, 3:40:01 PM9/22/11
to sy...@googlegroups.com
Hi,

Is there a way to compile sympy to javascript using pyjamas or another py/js compiler?

Pyjamas states that it could compile pure python projects, but I get an error when I try compiling sympy with it.
(Translating: core/facts.py [...] AttributeError:AssTuple instance has no attribute 'name')

Any ideas?

dennis

unread,
Sep 23, 2011, 1:16:31 PM9/23/11
to sympy
I have refactored some sympy code which has caused errors when
converting with pyjamas but it seems that i need to refactor all exec
calls. Pyjamas does not support exec calls.

Can someone of the dev team say how much effort it would need to
refactor all exec statements?

Aaron Meurer

unread,
Sep 23, 2011, 1:34:46 PM9/23/11
to sy...@googlegroups.com
Are you trying to convert all of SymPy, or just a reduced version
(e.g., just the core)?

I used "git grep 'exec '" on the repo to find all the statements. It
looks like your main problems are lines like

exec "from sympy import *" in global_dict

You may want to just skip some files, such as the test runner (and all
the tests, for that matter), and lambdify.py (which probably won't be
useful to you).

This mainly leaves the parser, which you'll probably want. I think you
could replicate the above code using __import__ (I'm not sure what the
exact code would look like at the moment).

Also, is eval() supported? I'm assuming not, since it's basically the
same as exec. This is a little harder to find by grepping, since we
have a lot of methods called eval, but I think there aren't really any
important ones (i.e., ones that you can't just remove file for).

By the way, could you perhaps push your refactoring up to a branch at
GitHub? It likely won't be merged (unless there are no side effects
from it), but I think it would still be interesting for people to see
what you needed to do, and perhaps it would help others who may want
to get it to run in pyjamas.

Aaron Meurer

> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To post to this group, send email to sy...@googlegroups.com.
> To unsubscribe from this group, send email to sympy+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
>
>

dennis

unread,
Sep 24, 2011, 9:48:57 AM9/24/11
to sy...@googlegroups.com
You are right, I don't need to convert the whole project. What I need for my current project is some school math (deriving/integrating/solving functions like "x^2", "x^3-3x+2", "sin(x)", "log(x)" etc.). I don't need most of the other code e.g. plotting.

So before refactoring the code I should probably check which modules I need to convert.

I forked sympy at github (I hope that I have done that right, I have never worked with it before...) and created a branch sympy2js where I sorted out some modules like plotting/benchmark.

Then I created a file runmin.py which contains:

from sympy.core.symbol import Symbol
print Symbol('x')

So I now want to sort out all modules that are not needed for this simple code and then try to refactor only the needed modules.

But when I for example delete the tensors folder I get some errors because it is included in many other modules. How should I find out which modules I can delete and which not? Do you have a list of the minimum required modules?

I don't think that eval() is supported by pyjamas. For example "print eval('4*4')" compiles fine but gives an error at runtime in the browser.

Aaron Meurer

unread,
Sep 24, 2011, 1:46:04 PM9/24/11
to sy...@googlegroups.com
You will probably need the core, functions, solvers (or at least the
parts of solvers that you want to support), and integration. You'll
aslo probably want the parsing module, as I noted.

You will actually find that the modules are more interlinked than you
might expect. For example, the functions module relies on the ntheory
module to evaluate some functions at numeric arguments (e.g.,
perfect_power is used in log.eval()).

There is a little graph of the dependencies of the modules in SymPy at
http://code.google.com/p/sympy/issues/detail?id=2103 (see the one from
comment 7). This may not be up to date, but I provide the code to
regenerate it.

You'll see from there that you will probably need to convert the polys
(this is almost as essential as the core for some operations), the
logic and assumptions modules, which are used for assumptions (I
wouldn't recommend trying to remove assumptions from the code), you'll
need the matrices and simplify for the solvers and integration modules
(and perhaps other things as well), and you might need some stuff from
utilities (which shouldn't cause too many problems with pyjamas, I
would think).

You can probably get rid of tensor by limiting the scope of which
functions you want to support.

If you just want to get Symbol('x') to work, you should start with
just the core, and work your way up from there. You can get a rough
idea of which modules are the most important by looking at what order
they are imported in sympy/__init__.py, since the ones that the others
depend on have to be imported first.

Aaron Meurer

> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.

> To view this discussion on the web visit
> https://groups.google.com/d/msg/sympy/-/jQKNmtFhCq4J.

Aaron Meurer

unread,
May 10, 2013, 2:42:06 PM5/10/13
to sy...@googlegroups.com
SymPy now has a javascript code printer. It's called jscode()

In [39]: jscode(sin(x) + sqrt(2) - x**2)
Out[39]: -Math.pow(x, 2) + Math.sin(x) + Math.sqrt(2)

Aaron Meurer


On Fri, May 10, 2013 at 3:05 AM, James <ift...@gmail.com> wrote:
Hi Dennis

Sorry to revive an old thread, but I am also looking into compiling sympy to javascript (also only the basic math) -  did you have success?
--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

To post to this group, send email to sy...@googlegroups.com.

Matthew Rocklin

unread,
May 10, 2013, 2:49:04 PM5/10/13
to sy...@googlegroups.com
Great!

dennis

unread,
May 12, 2013, 12:21:12 PM5/12/13
to sy...@googlegroups.com
Hi James

I did succeed in converting sympy to javascript. I ended up having some of the sympy core converted and loaded in the browser without syntax errors, but it did not work properly.


On Friday, May 10, 2013 11:05:51 AM UTC+2, James wrote:
Hi Dennis

Sorry to revive an old thread, but I am also looking into compiling sympy to javascript (also only the basic math) -  did you have success?


On Saturday, September 24, 2011 4:48:57 PM UTC+3, dennis wrote:

dennis

unread,
May 13, 2013, 8:16:00 AM5/13/13
to sy...@googlegroups.com
I am sorry, I do not have the original / converted source code anymore.

On Monday, May 13, 2013 1:55:35 PM UTC+2, Antony Shaleynikov wrote:
Dennis, is it possible to take a look at the result you get?
I'm pretty interested in SymPy running at browser as well.

Antony

воскресенье, 12 мая 2013 г., 19:21:12 UTC+3 пользователь dennis написал:

Buck Shlegeris

unread,
Nov 13, 2013, 1:10:09 PM11/13/13
to sy...@googlegroups.com
So how much effort and time do you think it would take to make this conversion work? I'd really like to use SymPy for a JS project -- currently, there's no Javascript CAS worth the name. If a few hours would possibly be able to get this to work, my team would have a go.

Buck

Aaron Meurer

unread,
Nov 13, 2013, 1:45:04 PM11/13/13
to sy...@googlegroups.com
Unless there is a *complete* Python to Javascript converter, or a
*full* Python interpreter in JS (I know of neither, but I don't do
much with Javascript), I wouldn't hold out much hope. I put "complete"
and "full" in stars, because SymPy really uses every corner of the
Python language. Anything that only handles a subset probably won't be
able to handle the everything that SymPy uses.

That isn't to say it isn't possible, though. Is there some object
oriented stack built on top of Javascript, preferably one similar to
Python? If so, you may be able to convert the basic core concepts from
SymPy. Also take a look at https://github.com/certik/sympyx and
https://github.com/certik/csympy to see what more stripped down
versions of the core might look like. Beyond that, the more
algorithms you need, the more work that's cut out for you. Building a
CAS is hard work. There's a reason there aren't too many of them.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.

Vinzent Steinberg

unread,
Nov 14, 2013, 12:59:09 PM11/14/13
to sy...@googlegroups.com
I don't know of anyone trying to get SymPy to run there, but there are Skulpt [1] and Brython [2], which implement Python on top of Javascript. Pyjs [3] translates Python to Javascript.
There are also approaches using PyPy, see for instance [4].

I have no Idea how much work it is to run SymPy on top of any of these, but given how it was for Jython and PyPy, I would be surprised if it worked out of the box. 

Vinzent

David Li

unread,
Nov 17, 2013, 2:04:49 PM11/17/13
to sy...@googlegroups.com
There's also the more speculative ideas of using Emscripten (example: http://repl.it/M4w) or Portable Native Client to compile the Python interpreter to JavaScript, then using that to run SymPy.

David

F. B.

unread,
Jan 10, 2014, 3:57:57 PM1/10/14
to sy...@googlegroups.com

On Sunday, November 17, 2013 8:04:49 PM UTC+1, David Li wrote:
There's also the more speculative ideas of using Emscripten (example: http://repl.it/M4w) or Portable Native Client to compile the Python interpreter to JavaScript, then using that to run SymPy.

I came across this project and, yes, I believe this is the right solution to run sympy in a browser (I didn't try but it's very promising as a project).

Let me explain a bit. Emscripten is a tool to be used along with clang compiler to compile C/C++ code to Javascript. The Javascript code generated is very strange, there are only arrays and integers as variables. That kind of javascript follows the ASM.js standard, and is meant to resemble a low-level language such as assembler rather than a high-level language such as javascript.

The code is likely to run on most browser. The point is that Firefox can detect when the code follows the AMS.js standard, and in such cases the javascript source code is not processed by the standard javascript interpreter, rather it is translated back to machine code, resulting in a compiled program to some degree similar to what a C/C++ compiler would have output. Performance is slightly less than by using a C/C++ compiler.

This fast mode is currently supported by Firefox only, other browsers will still run AMS.js-compliant code, but will rely on their standard javascript interpreter, thus being slower. Google Chrome and Opera are currently working to introduce this feature into their browsers.

The point is, that it is possible to compile CPython into Javascript, so as to have a 100% python compatible interpreter inside the browser. The link pointed out by David Li (http://repl.it/M4w) is CPython running inside the browser as javascript code. I would recommend to use Firefox, as other browsers will probably be very slow executing such an enormous amount of javascript with their standard interpreters.

Aaron Meurer

unread,
Jan 10, 2014, 8:13:38 PM1/10/14
to sy...@googlegroups.com
Are you sure about that? I did the following test on my Mac (Chrome
32.0.1700.72 beta, Firefox 26.0):

def sieve(n):
primes = range(2, n+1)
for i in range(2, n+1):
for j in primes[:]:
if not j % i and j != i:
primes.remove(j)
return primes

import time

t = time.time();sieve(1000);print(time.time() - t)

(yes I know it's inefficient; my point was just to find something that
did something nontrivial that took a reasonable but nontrivial amount
of time to complete).

In Chrome, I get 0.555000066757; in Firefox I get 2.47399997711. I
also tried Safai 7.0.1 (I get 4.63800001144) and Opera because you
mentioned it (version 12.16, I get 4.44400000572).

So maybe Chrome beta already has some of the ASM stuff in it, but
whatever it is, it's clearly the fastest here.

For reference, when I run it in IPython in my terminal I get
0.0159571170807. So it's still 30 times slower.

Aaron Meurer

David Li

unread,
Jan 10, 2014, 8:49:16 PM1/10/14
to sy...@googlegroups.com
I think the asm.js optimizations do make a difference when used; see a benchmark of a physics engine ported with Emscripten: http://josephg.com/blog/chipmunkjs-and-emscripten (though it's a bit outdated). Regardless, if Emscripten is too slow in Chrome we can fall back on Native Client (and actually, there's a project called pepper.js that compiles Native Client modules into JavaScript with Emscripten), and just getting it running in the browser would be a great accomplishment.

@F.B. have you managed to compile Python using Emscripten? I tried but could not get the interpreter working, it just hung/crashed if I tried to bundle the standard library and complained about site.py otherwise.

David

F. B.

unread,
Jan 11, 2014, 3:52:10 AM1/11/14
to sy...@googlegroups.com


On Saturday, January 11, 2014 2:13:38 AM UTC+1, Aaron Meurer wrote:

In Chrome, I get 0.555000066757; in Firefox I get 2.47399997711. I
also tried Safai 7.0.1 (I get 4.63800001144) and Opera because you
mentioned it (version 12.16, I get 4.44400000572).

So maybe Chrome beta already has some of the ASM stuff in it, but
whatever it is, it's clearly the fastest here.

For reference, when I run it in IPython in my terminal I get
0.0159571170807. So it's still 30 times slower.

I get similar performances on Linux (Firefox, Chrome, IPython). It looks like Google is actively working on ASM.js performance, so maybe the last version of Chrome already has optimized support for it.

F. B.

unread,
Jan 11, 2014, 4:34:14 AM1/11/14
to sy...@googlegroups.com


On Saturday, January 11, 2014 2:49:16 AM UTC+1, David Li wrote:

@F.B. have you managed to compile Python using Emscripten? I tried but could not get the interpreter working, it just hung/crashed if I tried to bundle the standard library and complained about site.py otherwise.


No, I didn't.

By the way, what about trying another way, namely:
  • translate sympy to C++ using Nuitka
  • compile the C++ code generated by Nuitka to javascript using clang/emscripten

Nuitka's aim is to be able to compile any python program to C++ and then to machine code. Nuitka's generated C++ code is independent of CPython, and thus has less boilerplate than running sympy inside a browser. I do not have much time, but if anyone is interested, that could be a nice experiment.

Reply all
Reply to author
Forward
0 new messages