Combine multiple fractions into one using SymPy (Python) - python

I have a symbolic expression (say, var_1) with is a sum of around ten fractions, each being a complex combination of many parameters. var_1 arises after performing several operations into other expressions. In other words, var_1 is an output and not an input. This is, I only have var_1 and not its individual components.
By construction, I know that when var_1 is written as one fraction (using the least common multiple as denominator), then the nominator is zero. I am confirming this with the SymPy library of Python (I am actually using SymPy in Julia but operations are the same).
I am looking for a function that combines multiple fractions into one, but applied to a single variable like var_1. factor(var_1) doesn't work. It seems SymPy stops factoring due to the complexity of the expression var_1. Any idea?

In fact, there are many standard functions that add up fractions in SymPy. For example, simplify, fraction, ratsimp, etc. See the developers section for a complete list of functions (link here).
The problem in my case is that the expression I have is too complex to be handled by those functions. Therefore the above functions return as output the same input. Yet, my problem was solved by the function powsimp with the option force=true. This is, I called powsimp(var_1,force=true) in Julia (I think it is powsimp(var_1,force=True) in Python). I am not sure myself why that option works but it does!

Related

Why is Scipy.spatial.distance.cdist fast if it uses a double for loop?

I've been told that double for loops are slow in Python. However, while digging into the implementation of Scipy.spatial.distance.cdist(), I found that it's just a double for loop and not some clever numpy trick. And yet, many answers (e.g. https://stackoverflow.com/a/62416370) recommend using cdist().
My question is: why is the function still so fast if it's just naively iterating over all elements in O(n^2)?
Function with two for loops that you are pointing to, _cdist_callable(), is not used in most cases. When you read cdist() function you can see that _cdist_callable() is run for example when you provide your own metric function.
In typical scenario, when you provide metric in form of a string: euclidean, chebyshev, cityblock, etc., C-optimized functions are being used instead.
And "handles" to those C-optimized functions for those metrics are listed here, in the same file.

Highly precise division, multiplication, and exponentiation of large complex numbers

I am working on a project that requires highly precise division of large numbers which will sometimes be complex numbers. I need to do this in python, preferably python 3.7, but everything I have tried so far has not worked at all.
With real numbers, I can simply use the decimal module, but I found the decimal module does not work for complex numbers. In addition, when I have tried to extend the decimal module to the complex numbers, it has failed as I get inaccurate results with both large real and large complex inputs. When trying to download external modules with the functionality, it has not worked.
from decimal import *
def div(a,b):
y = b.real - (b.imag*1j)
a = a*y
b = Decimal((b*y).real)
return [Decimal(a.real)/b,Decimal(a.imag)/b]
Here is my code for using the decimal module on complex numbers, and to demonstrate what I mean (and to demonstrate this method of division works) Ill show below some inputs and outputs. The first one will be the method of working with relatively small inputs, and the 2nd will be the method very much not working with a large input.
>>> div(13243,23)[0]*23
Decimal('13243.00000000000000000000000')
>>> div(15**17,23)[0]*23
Decimal('98526125335693355453.21739130')
The result from trying with 15**17 is not only a few thousand higher than 15**17, but it's also not a whole number. This is very incorrect. As said I need this method to be transferable to the complex numbers, and as it stands to store complex numbers in a list is a pain and not ideal. It was necessary to do so in order to use decimal on the parts though, however, it clearly hasn't worked.
I thought at first that perhaps it was a case of I just needed to set the precision higher, but even when set to 1000 it still fails.
At this point, I tried to find some modules that would allow me to do this. I found 2. mpmath and gmpy. I tried to install gmpy via pip, and I tried doing so on multiple versions of python and with multiple versions of gmpy, and each time I got an error message, normally one about a sever "actively refusing connection", as well as others saying it wasn't supported, etc.
This kind of leaves me stuck. I can't get the modules that do it for me, and when I try to do it myself it quite blatantly isn't working. Is there another module that provides this functionality out there or is there something I am particularly doing wrong with my attempts that can be fixed somehow?

Generate python code from a sympy expression?

The Question:
Given a sympy expression, is there an easy way to generate python code (in the end I want a .py or perhaps a .pyc file)? I imagine this code would contain a function that is given any necessary inputs and returns the value of the expression.
Why
I find myself pretty frequently needing to generate python code to compute something that is nasty to derive, such as the Jacobian matrix of a nasty nonlinear function.
I can use sympy to derive the expression for the nonlinear thing I want: very good. What I then want is to generate python code from the resulting sympy expression, and save that python code to it's own module. I've done this before, but I had to:
Call str(sympyResult)
Do custom things with regular expressions to get this string to look like valid python code
write this python code to a file
I note that sympy has code generation capabilities for several other languages, but not python. Is there an easy way to get python code out of sympy?
I know of several possible but problematic ways around this problem:
I know that I could just call evalf on the sympy expression and plug in the numbers I want. This has several unfortuante side effects:
dependency: my code now depends on sympy to run. This is bad.
efficiency: sympy now must run every time I numerically evaluate: even if I pickle and unpickle the expression, I still need evalf every time.
I also know that I could generate, say, C code and then wrap that code using a host of tools (python/C api, cython, weave, swig, etc...). This, however, means that my code now depends on there being an appropriate C compiler.
Edit: Summary
It seems that sympy.python, or possibly just str(expression) are what there is (see answer from smichr and comment from Oliver W.), and they work for simple scalar expressions.
That doesn't help much with things like Jacobians, but then it seems that sympy.printing.print_ccode chokes on matrices as well. I suppose code that could handle the printing of matrices to another language would have to assume matrix support in the destination language, which for python would probably mean reliance on the presence of things like numpy. It would be nice if such a way to generate numpy code existed, but it seems it does not.
If you don't mind having a SymPy dependency in your code itself, a better solution is to generate the SymPy expression in your code and use lambdify to evaluate it. This will be much faster than using evalf, especially if you use numpy.
You could also look at using the printer in sympy.printing.lambdarepr directly, which is what lambdify uses to convert an expression into a lambda function.
The function you are looking for to generate python code is python. Although it generates python code, that code will need some tweaking to remove dependence on SymPy objects as Oliver W pointed out.
>>> import sympy as sp
>>> x = sp.Symbol('x')
>>> y = sp.Symbol('y')
>>> print(sp.python(sp.Matrix([[x**2,sp.exp(y) + x]]).jacobian([x, y])))
x = Symbol('x')
y = Symbol('y')
e = MutableDenseMatrix([[2*x, 0], [1, exp(y)]])

SymPy: Safely parsing strings

SymPy comes equipped with the nice sympify() function which can parse arbitrary strings into SymPy expressions. But it has two major drawbacks:
It is not safe, as it relies on the notorious eval()
It automatically simplifies the read expression. e.g. sympify('binomial(5,3)') will return the expression 10.
So my questions are:
First, is there a way to "just parse" the string, without any additional computations? I want to achieve something like this effect:
latex(parse('binomial(5,3)')) #returns '{\\binom{5}{3}}'
Second, is there an accepted way to sympify (i.e. parse and compute) arbitrary user-generated strings while remaining safe? It is done by SymPy Gamma, so it's possible in practice, but the question is how much dirty work is needed.
Look at the internal functions in the SymPy parsing module.
There is no official way to do it. We need to rewrite sympify to avoid eval. Note that SymPy gamma just uses sympify. It remains safe because it's sandboxed on the App Engine.

Keep expression exactly as written for latex conversion

I want to get the expression of p__s_alpha = 1/k * Product(a_0,(i,1,O)) in latex. I use:
print sympy.latex(p__s_alpha)
When I run latex on the result I get the following equation:
However, I want to print this equation:
Is there a way to keep the representation of the expression the way it is?
I started writing up an answer about how you could make your own custom printer that does this, but this I realized that there's already an option in latex that does what you want, the long_frac_ratio option. If that ratio is small enough, any fraction that is small enough will be printed as 1/b*a instead of a/b.
In [31]: latex(p__s_alpha, long_frac_ratio=1)
Out[31]: '\\frac{1}{k} \\prod_{i=1}^{O} a_{0}'
If you're interested, here is some of what I was going to write about writing a custom printer:
Internally, SymPy makes no distinction between a/b and a*1/b. They are both represented by the exact same object (see http://docs.sympy.org/latest/tutorial/manipulation.html).
However, the printing system is different. As you can see from that page, a/b is represented as Mul(a, Pow(b, -1)), i.e., a*b**-1, but it is the printer that converts this into a fraction format (this holds for any printer, not just the LaTeX one).
The good news for you is that the printing system in SymPy is very extensible (and the other good news is that SymPy is BSD open source, so you can freely reuse the printing logic that is already there in extending it). To create a custom LaTeX printer that does what you want, you need to subclass LatexPrinter in sympy.printing.latex and override the _print_Mul function (because as noted above, a/b is a Mul). The logic in this function is not really split up modularly, so you'll really need to copy the whole source and change the relevant parts of it [as I noted above, for this one, there is already an option that does what you want, but in other cases, there may not be].
And a final note, if you make a modification that would probably be wanted be a wider audience, we would love to have you submit it as a pull request to SymPy.

Categories