Symbolics - JL A Modern Computer Algebra System For A Modern Language
Symbolics - JL A Modern Computer Algebra System For A Modern Language
The JuliaSymbolics Organization Roadmap We need new Computer Algebra Systems (CAS) for this new era of computing. We need a CAS
that dispatches in the multiple ways we think. We need a CAS that scales…
Show article ∠
We need new Computer Algebra Systems (CAS) for this new era of computing. We need a CAS that dispatches in the multiple ways
we think. We need a CAS that scales exponentially like our problems. We need a CAS that integrates with our package ecosystem,
letting people extend parts and
contribute back to the core library all in one language. We need a modern CAS in a modern language.
Symbolics.jl is the answer. Symbolics.jl is a pure Julia CAS which uses the Julia core library to its fullest. It is built from the ground up
with performance in mind. We use specialized structures for automatic simpliScation to match the performance of the most fully
optimized C++ libraries. It exploits parallelism at every level; our symbolic simpliScation takes advantage of Julia’s task-based
This reconstruction of the idea of CAS in Julia’s type system is entirely extensible. New term types enable fast symbolic arithmetic
on standard and non-standard algebras; add-on libraries like
ModelingToolkit build a bridge from symbolics to numerics. Symbolics.jl and its ecosystem will be the common foundation on which
the next generation of Domain-SpeciSc Languages (DSLs) will be constructed, automatically updated and accelerated through with
the growth of this system.
and much more. A lot of these features are for free given its deep integration with multiple dispatch and Julia’s type system.
Symbolics.jl grew out of ModelingToolkit.jl, an equation-based modeling system for the Julia programming language. Its vision is
that the best system for modeling requires having the ability to symbolically specify models and build a library of transformations for
generating more stable
and performant code. While software in a similar space like Simulink and Modelica are disconnected from traditional programming
languages and symbolic algebra systems, ModelingToolkit.jl weaves them together, allowing all aspects of the Julia programming
language and symbolic computing to contribute to the richness of its design.
The ModelingToolkit.jl project has been almost too much of a success in that respect, reaching a feature-base that included an entire
CAS as a submodule within itself. It was time for that CAS to be set free. Symbolics.jl is that CAS, now set in its own organization,
JuliaSymbolics, with its ability to transform new domains.
ModelingToolkit.jl will continue to provide the symbolic representations of common numeric systems and the SciML organization,
such as causal and acausal modeling (Simulink/Modelica) in the domains of:
It will continue to power the connection the next generation of symbolic-numeric computation, blurring the boundaries by mixing
analytical solutions with optimized and parallelized generated code. All symbolic functionality related to those domains will continue
to thrive in that package, leaving Symbolics.jl the room to focus on the core of symbolic algebras: polynomials, Grobner bases, and
more.
However, there are some use cases in computational algebra which require non-standard rulesets. How would you deSne symbolic
Octonian numbers or deSne differentiation on non-smooth manifolds that do not satisfy the Leibniz rule? For these questions,
mathematicians have traditionally been on their own having to develop new tools from scratch. However, the JuliaSymbolics has
refactored its core so that new algebras can easily be implemented and created, and automatically get the optimized high
performance of Symbolics.jl. This is SymbolicUtils.jl.
SymbolicUtils.jl is a fast and parallel rule-based rewrite system. By specifying a list of rules, such as trigonometric identities, you can
specify new mathematical domains and create the symbolic arithmetic that you need. Symbolics.jl is built on this foundation, adding
the common simpliScation rules for real numbers, derivative deSnitions and rules for Newton differentiation, and more. However, if
you’re so inclined, SymbolicUtils.jl is open for you to deSne BraKet algebras and more.
Feature Completeness
We want Symbolics.jl to be the place where you check the documentation immediately for symbolic methods, knowing that if such a
method exists then it’s implemented there. Symbolics.jl should not just cover the domain but also be an archive of its research and
science, making it easy to explore algorithms and compare between them.
Star our libraries like Symbolics.jl and our extensions like ModelingToolkit.jl. Such recognition drives our growth to sustain the
project.
Join our chatroom to discuss with us. Our main chatroom is #symbolic programming on the Julia Zulip
If you’re a student, Snd a summer project that interests you and apply for funding through Google Summer of Code or other
processes (contact us if you are interested)
Start contributing! We recommend opening up an issue to discuss Srst, and we can help you get started.
Help update our websites, tutorials, benchmarks, and documentation
Help answer questions on Stack Overkow, the Julia Discourse, and
other sites!
Hold workshops to train others on our tools.
There are many ways to get involved, so if you’d like some help Sguring out how, please get in touch with us.
This is in large part due to the amazing work of @shashi and @YingboMa, along with many others like @HarrisonGrodin,
@dpsanders, and @Mason who have been pushing on various aspects of this project in its infancy. Hopefully now it will be collected
to a place where it can thrive.
154 Likes
An even simpler example: f(x) = \frac{1}{2} \log \left( x_{1} \right) + \cdots +\frac{1}{2} \log \left( x_{N} \right)
f_{x_{i}} = \frac{1}{2x_{i}} for i \in \{1,\dots, N \}
Mathematica can’t compute this analytic derivative for general N-variables.
(I emailed them about this in 2009 & Steve said he was interested in this functionality. Doesn’t look like anything came of it…)
Can the new generation of CAS solve these types of problems (w/ N-variables)?
6 Likes
2 Likes
And then compute its analytic derivative, which in this case we know is:
f_{x_{i}} = \frac{1}{2x_{i}} for i \in \{1,\dots, N \}, N\geq 1
1 Like
http://www.matrixcalculus.org/
5 Likes
7 Likes
As a physicist, I’ve spent a little too much time in my life pasting (and then reformatting) expressions between Julia and
Mathematica. Very excited about these developments!
14 Likes
Do not underestimate however how important precise, complete but also accessible documentstion is. SymPy doc is so lovely!
6 Likes
Bill Helton (emeritus UCSD) has been developing a Mathematica package called NCAlgebra for noncommutative algebra. Maybe
some inspiration can be found there (at least for those with an access to Mathematica, but perhaps there is also free some viewer
for Mathematica notebooks).
3 Likes
Not the most productive comment, so somebody please let me know if it is not good discourse manners, but: wow. This is mind-
blowing.
22 Likes
Why would this be bad manners? There’s always space for people to praise others’ work and encourage them.
20 Likes
You can get rid of the piecewise result by imposing bounds on the indices, or by simplifying:
5 Likes
Is the intention for Symbolics.jl to eventually compete w/ CASs (SymPy, Mathematica, Maple etc)? SymPy already has >260k lines of
code…
While I’m sure CAS can work better in Julia, this feels like an insanely ambitious project for an already insanely busy organization.
I really hope you have funding/labor/craziness to make this work
3 Likes
Albert_Zevelev:
While I’m sure CAS can work better in Julia, this feels like an insanely ambitious project for an already insanely busy organization.
I really hope you have funding/labor/craziness to make this work
It’s already been one of SciML’s biggest projects for the last year, enough to be a full organization itself. It’s the foundation of
ModelingToolkit.jl. There’s also a lot of buy-in from industry partners. More on that at JuliaCon.
22 Likes
How hard would it be to modify Julia by removing all Irrational code and replacing it with Symbolics.jl? Irrational is in a weird
place, where it seems to kind of want to be part of a symbolic number system, but that obviously hasn’t happened.
2 Likes
I think removing ℯ an π from base would be a rather bad idea. The rest are kinda out of place and not being used in base itself from
what I’m aware.
The problem with having ℯ an π in Base is that it makes deSning operations like sin(π) into type piracy. Base currently has 6 extra
math functions (sinpi and friends) that could just be methods of sin if we had better symbolics.
1 Like
I really think that removing them would be wildly unpopular, whether or not it’s a good idea and they’re standing in the way of more
convenient CAS functionality in an external package. But I could deSnitely be wrong.
1 Like
It sounds like a breaking change to remove irrational ℯ and π, but perhaps there are other Unicode symbols that could denote the
symbolic versions and simplify things like sin(4*symbolicpi). People could choose to go with the one they prefer. I guess an issue
is the symbols should look su]ciently distinct to avoid confusion, while also su]ciently like ℯ and π to make sense to humans.
1 Like
This is amazing! There is a feature that has been the bane of many CAS implementations and has caused an enormous amount of
productive “bikeshedding” on the mailing lists of all open source CAS projects: assumptions
How will “assumptions” be dealt with in Symbolics.jl? I am asking as I remember how early on in Sympy there was much growing
pain related to the di]culty of adding a comprehensive assumption system after the library had already grown. Sympy ended up
having “new” and “old” assumption systems. And this has been a pain in many other older open source symbolic systems. It seems
incredibly hard to add such a system after the fact. And it does not seem to be listed in the parity with sympy issue.
What would be needed to do this with Symbolics.jl:
relevant links:
Personally, refine is one of the most important features for productive interactive work (after substitution).
19 Likes
next page →
READ THE ORIGINAL ARTICLE
natemcintosh
Karma: 196
Comments
Rackauckas has done a lot of work to create the whole scientiSc machine learning (SciML) ecosystem (with collaborators).
Symbolics.jl is the new step to a universal CAS tool in Julia to bridge the gap between symbolic manipulation and numerical
computation
It is especially useful as a foundation for equation-based simulation package ModelingToolkit.jl. In the foreseeable future, I expect
ModelingToolkit.jl can be comparable with the Modelica ecosystem to provide fast, accurate modeling and simulation capability and
easy integration with machine learning methods for Julia ecosystem, which is crucial for engineering application and scientiSc
research.
Thanks! The tutorials on the Modelica-like features of ModelingToolkit.jl are just starting to roll out. For example:
https://mtk.sciml.ai/dev/tutorials/acausal_components/ . Indeed, there's a lot to do in this space, but we already have some pretty
big improvements that we'll start writing down and share (hopefully) at JuliaCon 2021!
By vsskanth 2021-03-05 20:34
Hi Chris, I am a very heavy Modelica user and having an equivalent system in Julia is very welcome. Using Sciml's solvers in our
models would be a killer feature. Obviously, I am tempted to contrast ModelingToolkit.jl with Modelica and I have some
questions, if you don't mind:
Could you elaborate on the design choice to model components as functions as opposed to objects ? functions seem
compose well from your example but what about initial conditions and type safety ? In Modelica each component is an object
where you can specify initial conditions inside each of them with constraints and can eventually make a big system, and if it
compiles you can be reasonably conSdent you aren't mismatching units, missing outputs etc.
Do you have any plans for graphical representation ? Some of the systems I work on in Motorsports are absolutely massive
with 150k equations, and having a diagram to see the connections are really helpful. An auto generated one from code would
be more than good enough.
How do you handle FFI and interaction with other Julia objects inside ModelingToolkit.jl since it requires symbolic reduction ?
The FMI standard is a very popular export standard for these models. Any plans to support it here ?
I understand these are early days and I am very excited to know there's more on the pipeline. Thanks for your contribution.
Most of the answers to this will be in a big JuliaCon talk this summer. But I'll give a few hints.
>Could you elaborate on the design choice to model components as functions as opposed to objects ? functions seem
compose well from your example but what about initial conditions and type safety ? In Modelica each component is an
object where you can specify initial conditions inside each of them with constraints and can eventually make a big system,
and if it compiles you can be reasonably conSdent you aren't mismatching units, missing outputs etc.
There's things for type veriScation and all of that. The decision comes from how it interacts with the compiler. You can
easily redeSne functions and create them on the ky, less so for structs. That turns out to make it easier to do features like
inheritance easily in a functional workkow. Symbolic computing seems to work very well in this setup.
>Do you have any plans for graphical representation ? Some of the systems I work on in Motorsports are absolutely
massive with 150k equations, and having a diagram to see the connections are really helpful. An auto generated one from
code would be more than good enough.
Somewhat. Auto-generated ones from code already exist in the Catalyst.jl extension library (https://catalyst.sciml.ai/dev/).
That kind of graphing will get added to MTK: we just added the dependency graph tooling to allow it to happen, so it's just
waiting for someone to care.
>How do you handle FFI and interaction with other Julia objects inside ModelingToolkit.jl since it requires symbolic
reduction ?
All of the functions are Julia functions, and you can easily extend the system by registering new Julia functions to be
"nodes" that are not traced. See https://symbolics.juliasymbolics.org/dev/manual/functions/#R... . So if you do `f(x,y) =
2x^2 + y`, then it will eagerly expand f in your equations. If you do `@register f` (and optionally add derivative rules), then it'll
keep it as a node in the graph and put its function calls into the generated code. This is how we're doing FFI for media
libraries in a new HVAC model we're building.
>The FMI standard is a very popular export standard for these models. Any plans to support it here ?
There is a way to read in FMI that will be explained much more at JuliaCon, with some details probably shared earlier. It's
somewhat complex so I'll just wait till the demos are together, but yes we have examples with FMU inputs already working.
By vsskanth 2021-03-06 1:41
Thank you
Thank you for your hard work on SciML ecosystem and community, Rackauckas!
The new Modelica-like usage of ModelingToolkit.jl is really a game changer for acasual DAE system simulation in Julia. It
makes composable hierarchical component-based simulation of large and complex system possible with pure Julia.
Based on full featured dynamic simulation capability and machine learning ecosystem (Flux.jl etc), Julia will be a perfect choice
for reinforcenment learning research, where simulation and training process can all be implemented in pure Julia with
promising performance. It delivers the promise of "solve two language problem" of Julia language.
This is very cool. Computer Algebra Systems are like a super power. I’ve been able to use the TI-89’s arbitrary precision to do pretty
sophisticated cryptography work. Symbolics.jl has the ability to modify some of the rules of the algebra, which should allow even easier
implementation of number theory related cryptographic concepts (as well as compression and error correcting codes... or quaternions
or bra-ket quantum mechanics) without needing speciSc libraries. I love this as I’m trying to teach myself the fundamental concepts in
mathematical terms and not just something in a specialized black box library. (And without paying the insanely high price of
Mathematica if I ever want to use it professionally.)
I’ve looked brieky into Julia in the past, but if stuff like this becomes pretty standard (in the way numpy is for Python), I think I could
become pretty comfortable in Julia.
We already have a very good open source CAS called Maxima, which is implemented in Lisp. It is a descendent of Macsyma, the
oldest CAS, created at the MIT.
Maxima is quite awkward to use IME. Because of its age it has very nonstandard syntax for some things, like ":" for assignment,
and "(..., ..., ...)" for blocks of commands (equivalent to e.g. "{...; ...; ...}" in C, JavaScript, Java, etc.).
I prefer Sympy.
You are quite right to draw attention to this fact, but let the "geniuses" reinvent the wheel worse ;)
By reikonomusha 2021-03-05 18:45
CASes are one of the most di]cult things to write and they’re never complete. There are always bugs, performance concerns, anemic
mathematical domains, etc. Every major free or commercial CAS that’s still in use is under active development to battle these
inadequacies. Dozens of CASes have come and gone in the past 30 years, the majority of which have bitrotted or stopped being
maintained. And not a single CAS has reigned supreme as the CAS that beats all CASes.
It’s very exciting to see more work in CASes being done, but I worry that “starting a CAS from scratch” isn’t the right approach. The
Axiom [0, 1] project rightly identiSed that building a general-purpose CAS for working practitioners of computational mathematics is an
effort requiring nearly generational timespans [2], and that you must have the right language to describe mathematical objects and
their relationships. They had a literate programming policy, where all math code must be accompanied by publication-quality
documentation, precisely because it’s so hard to build and maintain these systems. Some of the greatest computational discoveries
and expositions came out of the development of Axiom, like the richest and most complete implementation of the renowned Risch
algorithm for doing symbolic integrals.
Axiom fell into disuse for a variety of reasons, but from my perspective, found new life in a fork called FriCAS [3, 4], which is actively
developed and allows a more “software engineer friendly” approach to the development of the system. The code they have is
enormously complex and has mountains of knowledge from foremost experts in computer algebra.
I really wish new computer algebra initiatives attempted in earnest to make use of and extend Axiom/FriCAS so that we could continue
to build up our knowledge of this exceedingly delicate and tricky subject without constantly starting from zero. Axiom has a manual
that is over 1,000 pages of dense mathematics and that’s really hard to rebuild correctly.
(The only project I know who honestly tried to build upon and subsequently extend CAS functionality is Sage [5], which builds upon a
plethora of existing open source general-purpose and specialized computational math systems.)
[0] https://en.m.wikipedia.org/wiki/Axiom_(computer_algebra_syst...
[1] http://www.axiom-developer.org/
> With that in mind I’ve introduced the theme of the “30 year horizon”. We must invent the tools that support the Computational
Mathematician working 30 years from now. How will research be done when every bit of mathematical knowledge is online and
instantly available? What happens when we scale Axiom by a factor of 100, giving us 1.1 million domains? How can we integrate theory
with code? How will we integrate theorems and proofs of the mathematics with space-time complexity proofs and running code? What
visualization tools are needed? How do we support the conceptual structures and semantics of mathematics in effective ways? How
do we support results from the sciences? How do we teach the next generation to be effective Computational Mathematicians? The
“30 year horizon” is much nearer than it appears.
[3] https://en.m.wikipedia.org/wiki/FriCAS
[4] http://fricas.sourceforge.net/
[5] https://www.sagemath.org/
One could argue that Julia also allows natural expression of mathematical algorithms. Coupled with Julia features like multiple
dispatch, high performance (due to Julia's LLVM backend) and growing ecosystem of AD and ML libraries, it seems like Julia is
probably the more “software engineer friendly” approach at this point. It doesn't seem odd that the Julia folk would want to
implement their CAS in Julia. That's not to say that maybe bridges from Julia to FriCAS couldn't be built as has been done with both
R and Python.
By dan-robertson 2021-03-06 0:32
There are lots of things which may go wrong trying to make a mathematics St into a type system. In particular you need a
particularly general typesystem. I think Julia has a better chance than haskell/rust/ml (let alone C++) because types are less
rigid so functions may return values of types that are functions of the arguments. The di]culty is subtyping.
For a trivial example, the integers under addition form a group. But they also form a ring, which is that group plus a different
monoid structure (and extra rules), and the real numbers form a Seld (two connected groups with extra structure) which meets
with the ring structure of the integers. If I write an algorithm about groups, I want a way to be able to apply it to the additive or
multiplicative groups of the reals. You need the ability to easily talk about forgetting extra structure but then taking results back
from the simpler structure.
Another example is dimensions. It is, as far as I know, basically impossible to encode something like “force (ie mass times
distance per time squared) divided by time is commensurate with current times voltage” in a type system like that in
ocaml/haskell/rust (you can maybe do it with c++ but the compiler can’t check that your template is correct)
The next problem with general algorithms is that there are isomorphisms and then there are isomorphisms so things that work
in mathematics (this group is cyclic and g is a generator so for my element h, there is some integer a such that g^a=h) are
sometimes infeasible on computers (the process described above is trivial in integers under addition, hard in integers mod p
under multiplication, and very hard in elliptic curve groups (of rank 1), even though they are all cyclic).
I don’t think these are reasons not to try and I think Julia feels like a good language for a combination of performance and
interface ergonomics, as well as the library being useful in the ecosystem of other scientiSc or mathematical libraries.
Regarding your point about dimensions, it really isn't impossible; it requires a little bit of type-level mechanisms, but not
very much and quite a few languages already have it.
Here are some examples in some languages.
The author of Libra (which I /think/ was the Srst to use this technique) gave a good talk [4] on the mechanism.
[4] https://www.youtube.com/watch?v=CrwVD0Pco5Q
Ok I guess I concede that it is technically possible in haskell and rust. But note that the way it works in both cases is
quite hacks, relying on typeclasses with associated types (ie effectively type-level functions) to fake numbers (up to
some maximum), and then representing the dimension of something as a Sxed length vector of these numbers. This is
Sne for dimensional analysis of real world physical things I guess but as soon as you’re trying to look at dimensions of
something to see if a calculation makes sense it will fail because there won’t be an appropriate slot in your vector, or
will need you to reimplement or modify the hacks.
I don’t think it is sustainable to need to jam that kind of trickery into every step.
I don't understand why you call it "trickery or "fake". Church encoding of natural numbers is the same technique
used in Agda, Coq and Idris to represent the Peano numbers. It's a completely valid encoding and isomorphic to any
other representation.
You don't need to use a Sxed-length array either - you can used a recursive linked list at the type-level for an
unbounded encoding [1]. The Scala library is an example of that; the Github page even has an example of encoding
arbitrary units like sheep and wheat.
[1] https://github.com/lloydmeta/frunk
The trickery here is basically pushing the type system to the extreme for relatively simple things. I wonder how
the type system might cope for more complicated things. Another consequence is type errors. You won’t get
something about trying to add a length to a time but rather something like “can’t unify type Pos1 with Zero,” or
“error Units<f64,(z,(z,(z,(z,(s<z>,(z,()))))))> does not implement trait Add<Units<f64,(z,(z,(z,(s<z>,(z,(z,()))))))>>.”
This is confusing enough in a trivial example but I wonder how this would go if the example were buried deep in
the code.
The encodings used in the haskell library were not a church encoding (they could only express integers between
about minus 9 and 9) though to be fair they claimed to be only there until better type level literals. I don’t know
about the rust implementation.
Coq and Idris are quite weird languages. The reason they use Peano arithmetic at the type level is that it is easy
for them to reason about. But in dependently typed languages where the type and value levels aren’t really
separate, if you want to prove things about your programs, they also need to use these numbers which means
you either need special language support for making them fast or you have slow programs, which is not
suitable for the topic of e]cient systems for computer mathematics. The other problem is that the computer
can’t help much with the types and they require a lot of manually specifying things which many practitioners
would consider trivial enough to be tacit. This is not good for having an expressive system for computer
mathematics.
Another example of a system which tried to offer better mathematical foundations is fortress. They started out
as something like “fortran but better at mathematics and without so much history” and ended up with
something a lot more like haskell with a typeclass-like mechanism and mostly function language. They had a
lot of issues with making the type system work with mathematics (one case is that it is hard to specify that
something can be a (eg) a monoid. In mathematics, it’s often obvious or said very simply, but computers aren’t
so good at knowing what is obvious. It can be complicated to say eg “this is a monoid with identity 1 and
operation x,” or “this is a monoid with identity 0 and operation +” because your type system needs a way to
disambiguate between the two monoids (or the language will need some bad ergonomics where it is very
manually expressed). If your type system ends up needing to know about the names of things and having eg
type classes dispatch on the operation or something, it could become tricky.
Rust is getting real type-level numbers in a couple of weeks. It’s just the bare minimum though. More to come in the
future.
Do you know whether there's going to be any near term support for ordering constraints (i.e. N < M) with the
type-level numbers?
By steveklabnik 2021-03-06 15:25
I don't.
We deSnitely can, should, and will interface with it. There's no reason to throw away great work. Just like how
DifferentialEquations.jl always had a focus on pure Julia solvers, it made sure to wrap every solver it could. Building such
wrappers is required for good research anyways, it's required for both timing and calculating e]ciency in other ways (like
amount of simpliScation or percentage of integrals solved).
Axiom, in its original commercial incarnation, took 20 years to build. My comment meant to suggest not spending another 20
for the dubious promise of a bit of additional “software engineer friendliness”, which is why FriCAS forked Axiom instead of
building one from scratch.