I have the following fraction:
import sympy as sp
a = sp.Symbol("a")
b = sp.Symbol("b")
a/(a+b)
And would like to print it as
1/(1+b/a)
I saw sympy had a factor function but I couldn't obtain the expected behaviour.
I thought I could maybe do something like:
sp.factor((a/(a+b)), a)
I would call this "distributing the numerator in the denominator":
>>> a/(a + b)
>>> 1/expand(1/_)
1/(1 + b/a)
You can use expand and collect
import sympy as sp
a = sp.Symbol("a")
b = sp.Symbol("b")
expanded = sp.expand(a/(a+b))
collected = sp.collect(expanded, a)
print(collected)
Related
Consider two sets i,j which both have m elements. Say we have an expression which describes a sum of terms. Each term can be described as a product of an element of i and j. Now, I would like to sum over each element of j, where each element has the range [i1,i2,...,im].
In the context of python & sympy, this is difficult since sympy's Sum describes the summation variable with (symbol,start,stop), which assume integer steps.
To demonstrate what I mean, consider the following code:
>>> from sympy import *
>>> i = symbols('i1,i2,i3,i4') # for the case m = 4
>>> j = symbols('j1,j2,j3,j4')
Here I use permutations to setup the expression:
>>> from itertools import permutations as perm
>>> c = list(perm(range(4),2))
>>> a,b = c[0]
>>> expr = i[a]*j[b]
>>> for a,b in c[1:]:
>>> expr += i[a]*j[b]
>>> print(expr)
i1*j2 + i1*j3 + i1*j4 + i2*j1 + i2*j3 + i2*j4 + i3*j1 + i3*j2 + i3*j4 + i4*j1 + i4*j2 + i4*j3
Now, using Sum over each j with range of i. It would be ideal if I could write one of the following:
>>> s = Sum(expr,(j,i))
>>> s = Sum(expr,(j1,i),(j2,i),...,(jm,i))
But that's not canonical with the sympy documentation. Are there any other methods which can be used to solve this problem?
Edit:
In this post, I tried to isolate the problem by only using elements i,j in expr. The full context problem is where expr is a sum of Kronecker Delta functions of i,j and using a sum over index set j, where each element of j has range i. For example:
>>> from sympy import KroneckerDelta as KD
>>> expr = KD(i[0],j[1]) # Only doing j[1] to reduce clutter
>>> print(expr)
KroneckerDelta(i1,j2)
>>> s = Sum(expr,(j[1],i)).doit()
>>> print(s)
# Desired output to look like:
1 + KroneckerDelta(i1,i2) + KroneckerDelta(i1,i3) + KroneckerDelta(i1,i4)
This is the reason for which I phrased my question as: summing over each element of j with range i.
IndexedBase can act as a symbolic, integer-indexed array:
>>> from sympy import *
>>> from sympy.abc import k,l
>>> i,j = map(IndexedBase,'ij')
>>> Sum(i[k]*j[l],(k,1,2),(l,1,2)).doit().expand()
i[1]*j[1] + i[1]*j[2] + i[2]*j[1] + i[2]*j[2]
>>> Sum(Piecewise((i[k]*j[l],Ne(k,l)),(0,True)),(k,1,2),(l,1,2)).doit()
i[1]*j[2] + i[2]*j[1]
It's not clear whether you want the cross terms when the indicices are the same, so both versions are shown.
I tried to solve this equation but still running.
I gave the symbol and the equation is "Eq((1-(1+ x )(-60))/ x+32*(1+x)(-60) , 41.81)".
The way solve and solveset usual work is to split an expression into numerator and denominator, and return solutions for the one that are not in the other.
Let's define a helper function to put the solutions from nsolve into a FiniteSet and one to give the final solution:
>>> from sympy import FiniteSet, nsolve, Add, Eq
>>> from sympy.abc import x
>>> rr = lambda x: FiniteSet(*[i[0] for i in real_roots(x, multiple=False)])
>>> sol = lambda n, d: list(rr(n) - rr(d))
>>> go = lambda eq: sol(*eq.rewrite(Add).as_numer_denom())
Now we try this out on your original expression:
>>> eq = Eq(32/(x + 1)**60 + (1 - 1/(x + 1)**60)/x, 41.81)
>>> fsol = go(eq) # very slow
>>> [i.n(3) for i in fsol]
[-3.33, -2.56, -1.44, -0.568, -0.228, 0.0220]
If you check those out by substituting into the original expression (written as an expression) you will find that only the last one is valid
>>> expr = eq.rewrite(Add)
>>> [expr.subs(x, i).n(3) for i in fsol]
[-42.1, -42.2, 4.72e+22, 2.64e+23, 1.97e+8, 1.31e-15]
Now let's replace that Float with a Rational and get solutions:
>>> req = nsimplify(eq, rational=True); req
Eq(32/(x + 1)**60 + (1 - 1/(x + 1)**60)/x, 4181/100)
>>> rsol = go(_) # pretty fast
>>> [i.n(3) for i in rsol]
[-2.00, 0.0220]
We know the 2nd solution is right; let's check the first:
>>> req.subs(x, rsol[0]).rewrite(Add).n(3)
-0.e-114
So both solutions appear to be valid and you don't get any spurious solutions which (by the way) I wasn't expecting from nsolve.
An exact analytic solution to this is unlikely but you can get numeric solutions e.g.:
In [18]: nsolve(eq, x, -2)
Out[18]: -1.99561339048822
Since this can be transformed into a polynomial you can find all real solutions like:
In [20]: p = Poly(nsimplify(eq).rewrite(Add).as_numer_denom()[0])
In [21]: [r[0].n() for r in p.real_roots(multiple=False)]
Out[21]: [-1.99561339048822, -1.0, 0, 0.0219988833527669]
Using as_numer_denom like this can potentially introduce spurious solutions though so you should check them (e.g. by plotting the function around each root). For example 0 is not actually a root.
I am trying to do fraction using sympy, I know sympy is supports symbolic but can it be done with old fraction, please know that I want it to be display it as unevaluatedexpr here is my code.
from sympy import *
s = (3)/(2) + (4) / (6)
display(s)
init_printing()
>>> import sympy
>>> a = sympy.Rational(3, 2)
>>> b = sympy.Rational(4, 6)
>>> a
3/2
>>> b
2/3
Alhamdulilaah I found it how to do it this is how you do it
from sympy import *
r = Rational(3,2)+Rational(4,2)
display(r)
I'm using Sympy to calculate derivatives and some other things. I tried to calculate the derivative of "e**x + x + 1", and it returns e**x*log(e) + 1 as the result, but as far as I know the correct result should be e**x + 1. What's going on here?
Full code:
from sympy import *
from sympy.parsing.sympy_parser import parse_expr
x = symbols("x")
_fOfX = "e**x + x + 1"
sympyFunction = parse_expr(_fOfX)
dSeconda = diff(sympyFunction,x,1)
print(dSeconda)
The answer correctly includes log(e) because you never specified what "e" is. It's just a letter like "a" or "b".
The Euler number 2.71828... is represented as E in SymPy. But usually, writing exp(x) is preferable because the notation is unambiguous, and also because SymPy is going to return exp(x) anyway. Examples:
>>> fx = E**x + x + 1
>>> diff(fx, x, 1)
exp(x) + 1
or with exp notation:
>>> fx = exp(x) + x + 1
>>> diff(fx, x, 1)
exp(x) + 1
Avoid creating expressions by parsing strings, unless you really need to and know why you need it.
I want to integrate exp(-(x^2 + y^2)) in python using sympy library.
I could find the integral of exp(-(x^2))
>>> B1 = sympy.exp(-alpha1 * (r1_x**2))
>>> p = integrate(B1,r1_x)
>>> p
pi**(1/2)*erf(alpha1**(1/2)*r1_x)/(2*alpha1**(1/2))
But when I want to try integrate exp(-(x^2 + y^2))
>>> B1 = sympy.exp(-alpha1 * (r1_x**2 + r1_y**2))
>>> p = integrate(B1,r1_x)
>>> p
Integral(exp(-alpha1*(r1_x**2 + r1_y**2)), r1_x)
There is no output and python can't take the integral!
(I am the lead developer of SymPy)
DSM is correct that you can get this to work by calling expand, and that there is no general way to do this (because in general, integrals don't have closed forms).
I just wanted to point out that if SymPy cannot do an integral that does have a closed form, we consider this a bug, and you should feel free to report it at http://code.google.com/p/sympy/issues.
sympy doesn't always recognize every form, and so sometimes you have to give it a little help:
>>> import sympy
>>> alpha1, r1_x, r1_y = sympy.var("alpha1 r1_x r1_y")
>>> B1 = sympy.exp(-alpha1 * (r1_x**2 + r1_y**2))
>>> B1.integrate(r1_x)
Integral(exp(-alpha1*(r1_x**2 + r1_y**2)), r1_x)
>>> B1.expand(alpha1)
exp(-alpha1*r1_x**2)*exp(-alpha1*r1_y**2)
>>> B1.expand(alpha1).integrate(r1_x)
sqrt(pi)*exp(-alpha1*r1_y**2)*erf(sqrt(alpha1)*r1_x)/(2*sqrt(alpha1))