SymPy was the project that got me into open-source nearly ten years ago (through Google Code-In), and I'm happy they're still being developed (and that my contributions, somehow, are still alive and kicking). I don't have much of a use for it anymore, but it was a great help through high school and college.
Yes, I wrote a control system modeling, simulation, and tuning optimization package for a previous employer that used sympy. Sympy allowed it to do symbolic modeling in parallel with numerical simulation; you could pick any two nodes in an arbitrary system and get the symbolic transfer function from one to the other, and generate Bode plots and such. For nonlinear systems it could linearize about some operating point, and for tuning, sympy helped derive an objective function to pass to the optimization routine.
Sympy was a little slow sometimes but very powerful and pretty easy to work with.
We're considering open sourcing that project now; I just need to find time to support it.
So you would model the equations on the fly for a certain optimization problem? If so, can you expand on the problems you were solving?
I'm trying to solve a similar sounding problem where I have to build the model equations from scratch quite often and right now it's using templates to recompile my binary with new equations whenever I need to do so, but that takes time and I have to manage a lot of code complexity. I'm doing it for performance reasons right now because other methods I tried we too slow, but it's getting unwieldily.
Sympy is great for this, because you can manipulate the equations symbolically, cancel terms, and then convert the result to a numerical routine using lambdify.
In my case, I'd build up a model of a motor control system using subsystems (motor model, inverter, current sensors, delay elements, noise sources, etc). Then design a feedback/feedforward control system (eg. PID) and connect that in as another block.
Each block has simulation code associated with it, and a matching symbolic sympy transfer function from each input to each output was derived.
When you connect them together with various feedback loops, it creates a directed graph that it then resolves using NetworkX to find the various loops, and using Mason's rule to solve the system transfer functions. For discrete time systems cycles were automatically resolved by inserting additional delay elements.
Each system composed internally of such parts could also be used as a single part in a larger feedback system, so for example, you can build up a current control loop around your motor and inverter, and then plug that as a subsystem into a velocity control loop.
You only have to write out the symbolic model of the base level components (inductors, resistors, etc). The equation for each transfer function along each signal path gets built up by Sympy, using the normal rules; for example a feedback loop with gain A becomes 1/(1+A). For a big system the equation gets quite complicated to write out in full.
Once you've assembled your system that way, you'll have a lot of parameters to tune. You can run the the resulting system in simulation and play with it but for tuning many variables at once, you'll want a more robust solution.
So from control theory we can derive certain objectives that we want to maximize, and constraints that we want to satisfy. The constraints might include a maximum value on the transfer function from a noise input to the motor current, or something like that, and of course Nyquist stability. The objective might include minimizing sensitivity to disturbances within a frequency band or minimizing time to converge to a target.
In such cases, you could perhaps simulate the system and derive those numerically, but it would be slow to do that. Much faster to solve them symbolically -- the expression for a sensitivity is easy when you know the transfer functions; you'll just have to take some limits as certain terms go to zero or infinity and take derivatives of those and so on. Then you get a function of your tuning parameters to optimize under constraints.
That can then get passed to an optimizer routine, to solve for your tuning parameters. Then you simulate the system to check that the performance is good.
Excellent! I think that's exactly what I was looking for! Thank you so much for going into detail on that, it helped immensely.
I have a similar problem (though can't talk too many details) with discrete "ticks" and with a constrained CPU (a peak constraint, I have plenty of aggregate CPU power over time). I think I could fit some simple version of the symbolic module optimizer algorithm like you describe into the unused CPU time to optimize the spiky algorithm before I receive events (the events are spread apart pretty good) to return more accurate and timelier results when they do come. I am using a Haskell-like language for this that compiles to a binary format with a similar graph reduction scheme for the compiler as you describe for the symbolic reducer, so it should be very simple for me to compose the modules as you describe.
The problem I have now is that when I need to calculate something that's very-high-priority (some events have hard deadlines), I would like to have a more optimized algorithm, but I don't have time to optimize it on the fly from the information I know (my knowledge is continuous, only the events are discrete), so I have to use less-accurate results or sometimes I don't have an answer so I just return a "no answer" response and the process fails. I tried using some crappy default values, but it would still fail most of the time.
I think about my problem like a process which has a target and my answer is the "direction to aim at" for the process and so if I return a bad result to this process it'll just miss the target, so I just say "sorry, can't aim right now, wait 1 more tick" and I then am able to start a calculation for the next round before the process even asks for it and it finishes easily this time, since my events have a low frequency. Using an optimal algorithm (which I can get from a symbolic reduction: that's how I did it--by hand--in the first place to get my current algos) will always return the answer in time, based on my models and experiments.
For my control theory lectures I made a numerical simulator based on scipy ode solvers. With a small library I was able to make a block diagram and simulate closed system response for arbitrary input. You have to create blocks(which is basically derivatives and outputs), put them in model and define interconnections. It is simple but pretty flexible. I am now trying to properly implement subsystems, and maybe gui for drawing block diagrams.
I would be super interested to see what you made with sympy. Can you show an example project using it, or put notification if you ever make it open source?
I use it in jupyter notebooks for structural engineering calcs. In a sense, it's definitely overkill, but it allows the following functionality:
When you create an expression, you have the ability to print it out in a nice readable format to verify it is correct and then without really ever altering that expression object, you can simultaneously perform simplifications and calculate final results.
IMO there's less opportunity for errors like omitting an asterisk on a term meant to be an exponent, or incorrectly simplifying.
Critically though, it allows me to hand my work over to someone who doesn't know python to check my work.
I definitely can replicate a lot of that same functionality without sympy, but I have to perform the substitutions and simplifications by hand, and the printing of the expression by rendering in LaTex is always different from the calculation, so I have to hand verify that I calculated what I said I was going to.
SymPy is pretty niche, but it saved my butt many years ago in my years of collegiate robotics. We spent months unsuccessfully trying to compute kinematics and sensor coordinate transformations on vectors of quarternions by “hand” with numpy. I wouldn’t wish it on my worst enemy. There are so many opportunities for mistakes, and the intermediate numbers can rarely be checked against your intuition.
With SymPy however (and some optional Newtonian physics package), one can simply define their free-bodies and coordinate systems, and SymPy will spit out simplified, compiled tensors of whatever expressions they want! It was truly magical at the time.
I don't know; I use isympy (interactive sympy, uses IPython if installed) as a local Wolfram Alpha for all my math problems, and it's really good at that.
Maybe like me, they grew up in a country where mathematics itself is pronounced "mathematica" (which is a huge fraction of languages [0]), leading to avoiding that name for the software.
I was grappling some very similar problem, and working with numerical results to verify intermediate results wasn't helpful and finally had to turn to maxima to final give analytically derived and simplified expressions.
These symbolic tools can save ones skin on a bad day.
I wrote an "anything-regressor" in SymPy, where you provide an equation (like y=mx+b) and a dataset of x's and y's, and it solves for constants to get a line of best fit. Super simple to implement and worked for any equation (quartic, logistic, etc) and any dimension of input variables.
Eventual goal was trying to implement something like XGBoost, but by applying successive regression equations to the residuals instead of successive decision trees. E.g. figure out that a sin wave best fits the initial data, and then a linear best explains the remaining difference.
Worked pretty well on toy data sets, but was much too slow to scale to anything real. Still think the idea has promise for producing human interpretable ML models.
Similar situation here. I needed to optimize a critical C++ function that took two 3D line segments and returned a transform matrix that would transform the first line segment into the second. I was able to completely remove the matrix multiplications from the function by using SymPy to pre-compose the scale/rotate/translate matrices and simplify the result, and the benchmarks showed a significant speedup.
An oversimplified explanation. SymPy is a non-interactive toolkit for balancing the numerical coefficients of a system of nonlinear equations. FYI a "system" in this sense is a math term. I also found that SymPy is too niche because it's not interactive.
I admit to being frustrated by the SymPy documentation. It does an adequate job of explaining "what" (i.e. the mechanics of each function or class), but I cannot read it to get an idea of the "how" or "why" questions, of how to best use SymPy to accomplish my goals.
Symbolic computation deals with the computation of mathematical objects symbolically. This means that the mathematical objects are represented exactly, not approximately, and mathematical expressions with unevaluated variables are left in symbolic form.
I really hope that sympy would improve to a point where I could use it. But as long as Fourier transforms are as badly broken as they are (see e.g. issues [1], [2] and [3]) I can't use it. And the fact that it doesn't fail or crash but gives wrong answers doesn't inspire much trust.
This library is on my todo list to learn and master. Not as intuitive as Mathematica, as variables are second rate citizens, but it is hard to beat the price. Also, Python integration is very nice as well.
Of note, octave's official symbolic package is effectively a sympy wrapper, mapping matlab's symbolic api to the equivalent sympy functionality. Very nice project. https://github.com/cbm755/octsympy
SymPy is great! I use it at work in an in-house web application where the user designs a graph (using d3.js). The graph nodes are electric energy meters, and so there are certain flows thru them. A system of equations is generated and then solved using SymPy, so one can find out what the flow is in a certain node in terms of the flows in the others.
Sympy is an incredible versatile tool. Last semester when I was TA for a linear algebra 101 course, I used it to generate 30-ish different versions of an homework based on a LaTeX template to output the questions for the students and the answers to facilitate the correction after in two separate pdf.
35 comments
[ 4.0 ms ] story [ 86.3 ms ] threadSympy was a little slow sometimes but very powerful and pretty easy to work with.
We're considering open sourcing that project now; I just need to find time to support it.
I'm trying to solve a similar sounding problem where I have to build the model equations from scratch quite often and right now it's using templates to recompile my binary with new equations whenever I need to do so, but that takes time and I have to manage a lot of code complexity. I'm doing it for performance reasons right now because other methods I tried we too slow, but it's getting unwieldily.
In my case, I'd build up a model of a motor control system using subsystems (motor model, inverter, current sensors, delay elements, noise sources, etc). Then design a feedback/feedforward control system (eg. PID) and connect that in as another block.
Each block has simulation code associated with it, and a matching symbolic sympy transfer function from each input to each output was derived.
When you connect them together with various feedback loops, it creates a directed graph that it then resolves using NetworkX to find the various loops, and using Mason's rule to solve the system transfer functions. For discrete time systems cycles were automatically resolved by inserting additional delay elements.
Each system composed internally of such parts could also be used as a single part in a larger feedback system, so for example, you can build up a current control loop around your motor and inverter, and then plug that as a subsystem into a velocity control loop.
You only have to write out the symbolic model of the base level components (inductors, resistors, etc). The equation for each transfer function along each signal path gets built up by Sympy, using the normal rules; for example a feedback loop with gain A becomes 1/(1+A). For a big system the equation gets quite complicated to write out in full.
Once you've assembled your system that way, you'll have a lot of parameters to tune. You can run the the resulting system in simulation and play with it but for tuning many variables at once, you'll want a more robust solution.
So from control theory we can derive certain objectives that we want to maximize, and constraints that we want to satisfy. The constraints might include a maximum value on the transfer function from a noise input to the motor current, or something like that, and of course Nyquist stability. The objective might include minimizing sensitivity to disturbances within a frequency band or minimizing time to converge to a target.
In such cases, you could perhaps simulate the system and derive those numerically, but it would be slow to do that. Much faster to solve them symbolically -- the expression for a sensitivity is easy when you know the transfer functions; you'll just have to take some limits as certain terms go to zero or infinity and take derivatives of those and so on. Then you get a function of your tuning parameters to optimize under constraints.
That can then get passed to an optimizer routine, to solve for your tuning parameters. Then you simulate the system to check that the performance is good.
I have a similar problem (though can't talk too many details) with discrete "ticks" and with a constrained CPU (a peak constraint, I have plenty of aggregate CPU power over time). I think I could fit some simple version of the symbolic module optimizer algorithm like you describe into the unused CPU time to optimize the spiky algorithm before I receive events (the events are spread apart pretty good) to return more accurate and timelier results when they do come. I am using a Haskell-like language for this that compiles to a binary format with a similar graph reduction scheme for the compiler as you describe for the symbolic reducer, so it should be very simple for me to compose the modules as you describe.
The problem I have now is that when I need to calculate something that's very-high-priority (some events have hard deadlines), I would like to have a more optimized algorithm, but I don't have time to optimize it on the fly from the information I know (my knowledge is continuous, only the events are discrete), so I have to use less-accurate results or sometimes I don't have an answer so I just return a "no answer" response and the process fails. I tried using some crappy default values, but it would still fail most of the time.
I think about my problem like a process which has a target and my answer is the "direction to aim at" for the process and so if I return a bad result to this process it'll just miss the target, so I just say "sorry, can't aim right now, wait 1 more tick" and I then am able to start a calculation for the next round before the process even asks for it and it finishes easily this time, since my events have a low frequency. Using an optimal algorithm (which I can get from a symbolic reduction: that's how I did it--by hand--in the first place to get my current algos) will always return the answer in time, based on my models and experiments.
I would be super interested to see what you made with sympy. Can you show an example project using it, or put notification if you ever make it open source?
https://docs.sympy.org/dev/modules/physics/control/
We'd love for this to be improved and grow.
When you create an expression, you have the ability to print it out in a nice readable format to verify it is correct and then without really ever altering that expression object, you can simultaneously perform simplifications and calculate final results.
IMO there's less opportunity for errors like omitting an asterisk on a term meant to be an exponent, or incorrectly simplifying.
Critically though, it allows me to hand my work over to someone who doesn't know python to check my work.
I definitely can replicate a lot of that same functionality without sympy, but I have to perform the substitutions and simplifications by hand, and the printing of the expression by rendering in LaTex is always different from the calculation, so I have to hand verify that I calculated what I said I was going to.
With SymPy however (and some optional Newtonian physics package), one can simply define their free-bodies and coordinate systems, and SymPy will spit out simplified, compiled tensors of whatever expressions they want! It was truly magical at the time.
I don't know; I use isympy (interactive sympy, uses IPython if installed) as a local Wolfram Alpha for all my math problems, and it's really good at that.
It’s called Mathematica, son.
[0] https://www.indifferentlanguages.com/words/mathematics
These symbolic tools can save ones skin on a bad day.
Eventual goal was trying to implement something like XGBoost, but by applying successive regression equations to the residuals instead of successive decision trees. E.g. figure out that a sin wave best fits the initial data, and then a linear best explains the remaining difference.
Worked pretty well on toy data sets, but was much too slow to scale to anything real. Still think the idea has promise for producing human interpretable ML models.
sympy.physics.vector (https://docs.sympy.org/dev/modules/physics/vector/index.html
and
sympy.physics.mechanics (https://docs.sympy.org/dev/modules/physics/mechanics/index.h...)
You can ultimately simulate and visualize dynamical systems:
https://pydy.readthedocs.io/en/latest/examples/multidof-holo...
> SymPy is a Python library for symbolic mathematics.
Both the release notes as well as the readme of the github repository don't explain it (or at least I couldn't find it).
You can play with it here! (Not this latest release though, apparently)
I feel like there's a missing manual somewhere.
Symbolic computation deals with the computation of mathematical objects symbolically. This means that the mathematical objects are represented exactly, not approximately, and mathematical expressions with unevaluated variables are left in symbolic form.
Let’s take an example...
The first thing in the README is this banner saying
> Python Library for Symbolic Mathematics
https://raw.githubusercontent.com/sympy/sympy/master/banner....
also the "About" snippet in github has
> A computer algebra system written in pure Python
1: https://github.com/sympy/sympy/issues/2803 2: https://github.com/sympy/sympy/issues/7178 3: https://github.com/sympy/sympy/issues/18136
https://colab.research.google.com/drive/1AS4IrzG-DJrrD49gVNH...
2020 https://news.ycombinator.com/item?id=23747133
2019 https://news.ycombinator.com/item?id=20287486
Lots in 2014:
https://news.ycombinator.com/item?id=8243452
https://news.ycombinator.com/item?id=8109265
https://news.ycombinator.com/item?id=7214783
https://news.ycombinator.com/item?id=7145219
2012 https://news.ycombinator.com/item?id=4463471
2011 https://news.ycombinator.com/item?id=3141699