How to factor exponential terms in Sympy Python? - python

How do I transform an expression like this:
y = [x*e^(x/2) + e^x + e^(x/2)]^2
in this:
y = {e^(x/2)*[x + e^(x/2) + 1]}^2
using Sympy??

It seems that the factoring doesn't recognize the exponential as well as a power. So convert the exp(x/2) -> y, factor, then back substitute:
>>> eq
(x*exp(x/2) + exp(x/2) + exp(x))**2
>>> factor(eq.subs(exp(x/2),y)).subs(y,exp(x/2))
(x + exp(x/2) + 1)**2*exp(x)

Related

sympy not ignoring unimportant decimals in exponential expression

I have a code that calculate some mathematical equations and when I want to see the simplified results, it can not equate 2.0 with 2 inside power, which is logical since one is float and the other is integer. But decision was sympys where to put these two values, not mine.
Here is the expression in my results that sympy is not simplifying
from sympy import *
x = symbols('x')
y = -exp(2.0*x) + exp(2*x)
print(simplify(y)) # output is -exp(2.0*x) + exp(2*x)
y = -exp(2*x) + exp(2*x)
print(simplify(y)) # output is 0
y = -2.0*x + 2*x
print(simplify(y)) # output is 0
y = -x**2.0 + x**2
print(simplify(y)) # output is -x**2.0 + x**2
is there any way working around this problem? I am looking for a way to make sympy assume that everything other than symbols are floats, and preventing it to decide which one is float or integer.
this problem has been asked before by Gerardo Suarez but not with a satisfactory answer.
There is another sympy function you can use called nsimplify. When I run your examples they all return zero:
from sympy import *
x = symbols("x")
y = -exp(2.0 * x) + exp(2 * x)
print(nsimplify(y)) # output is 0
y = -exp(2 * x) + exp(2 * x)
print(nsimplify(y)) # output is 0
y = -2.0 * x + 2 * x
print(nsimplify(y)) # output is 0
y = -(x ** 2.0) + x ** 2
print(nsimplify(y)) # output is 0
Update
As #Shoaib Mirzaei mentioned you can also use the rational argument in the simplify() function like this:
simplify(y,rational=True)

Sympy Subs not replacing a symbol when its power is being replaced

I'm trying to make some basic substitutions but SymPy doesn't want to help me out
x, y, z, k = symbols("x y z k", positive=True, real=True)
exp = x**4 + x**3 + x**2 + x
what_im_expecting = simplify(y**(Rational(1/4)) + y**(Rational(3/4)) + sqrt(y) + y)
what_i_actually_get = exp.subs(x**4,y)
exp, what_i_actually_get, what_im_expecting
returns
x + y**(Rational(3, 4)) + sqrt(y) + y
Can anyone help me out?
a more complex example:
The method subs can be trusted to replace the terms that exactly match the given "old" expression, which x**4 here. The replacement of other things related to x**4 is not so certain. (There are many open issues with subs: some say it substitutes too much, some say too little.) There is some substitution logic specific to powers, but x by itself is not formally a power, so it escapes that logic. A workaround: temporarily replace x by x**1, preventing automatic evaluation of that power to x.
x1 = sp.Pow(x, 1, evaluate=False)
subbed = exp.subs(x, x1).subs(x**4, y).subs(x1, x)
Now subbed is y**(3/4) + y**(1/4) + sqrt(y) + y.
But, don't expect human-like ingenuity from subs. With the same workaround, trying to do subs(x**4 - 1, y) results in x**3 + x**2 + x + y + 1: nothing like sqrt(y+1), etc, appears. It's better to substitute in the most direct way possible:
subs(x, (y+1)**Rational(1, 4))
Then you don't need any workarounds.

How do I simplify the sum of sine and cosine in SymPy?

How do I simplify a*sin(wt) + b*cos(wt) into c*sin(wt+theta) using SymPy? For example:
f = sin(t) + 2*cos(t) = 2.236*sin(t + 1.107)
I tried the following:
from sympy import *
t = symbols('t')
f=sin(t)+2*cos(t)
trigsimp(f) #Returns sin(t)+2*cos(t)
simplify(f) #Returns sin(t)+2*cos(t)
f.rewrite(sin) #Returns sin(t)+2*sin(t+Pi/2)
PS.: I dont have direct access to a,b and w. Only to f
Any suggestion?
The general answer can be achieved by noting that you want to have
a * sin(t) + b * cos(t) = A * (cos(c)*sin(t) + sin(c)*cos(t))
This leads to a simultaneous equation a = A * cos(c) and b = A * sin(c).
Dividing the second equation by the second, we can solve for c. Substituting its solution into the first equation, you can solve for A.
I followed the same pattern but just to get it in terms of cos. If you want to get it in terms of sin, you can use Rodrigo's formula.
The following code should be able to take any linear combination of the form x * sin(t - w) or y * cos(t - z). There can be multiple sins and cos'.
from sympy import *
t = symbols('t', real=True)
expr = sin(t)+2*cos(t) # unknown
d = collect(expr.expand(trig=True), [sin(t), cos(t)], evaluate=False)
a = d[sin(t)]
b = d[cos(t)]
cos_phase = atan(a/b)
amplitude = a / sin(cos_phase)
print(amplitude.evalf() * cos(t - cos_phase.evalf()))
Which gives
2.23606797749979*cos(t - 0.463647609000806)
This seems to be a satisfactory match after plotting both graphs.
You could even have something like
expr = 2*sin(t - 3) + cos(t) - 3*cos(t - 2)
and it should work fine.
a * sin(wt) + b * cos(wt) = sqrt(a**2 + b**2) * sin(wt + acos(a / sqrt(a**2 + b**2)))
While the amplitude is the radical sqrt(a**2 + b**2), the phase is given by the arccosine of the ratio a / sqrt(a**2 + b**2), which may not be expressible in terms of arithmetic operations and radicals. Hence, you may be asking SymPy to do the impossible. Better use floating-point values, but you do not need SymPy for that.

Convert a polynomial w(z) to w((1-z)/(1+z))

I am writing a code which takes a "code" (Coding Theory) as an input and I have calculated the weight enumerator of it. I want to find the weight enumerator of dual code using MacWilliams Identity.
I have W(z), the weight enumerator of the code, and I want to convert it to W((1-z)/(1+z)) using python.
If you are going to be working with polynomials in an extended fashion, you should be working with a proper computer algebra system (CAS). sympy is great for manipulations like these. For example:
from sympy import poly
from sympy.abc import x,z
W1 = poly(x**2 + 3*x)
# Evaluate the polynomial at x=(1-z)/(1+z)
W2 = W1((1-z)/(1+z))
print W1
print W2
>>> Poly(x**2 + 3*x, x, domain='ZZ')
>>> (-2*z**2 - 2*z + 4)/(z**2 + 2*z + 1)
You can simplify any answer with sympy.simplify and .expand for example:
import sympy
expr = (4*x**2 - 4*x + 4)*(x**3 + 3*x**2 + 3*x + 1)/(4*(x**2 + 2*x + 1))
print sympy.simplify(sympy.expand(expr))
>>> x**3 + 1

numpy.poly1d , root-finding optimization, shifting polynom on x-axis

it is commonly an easy task to build an n-th order polynomial
and find the roots with numpy:
import numpy
f = numpy.poly1d([1,2,3])
print numpy.roots(f)
array([-1.+1.41421356j, -1.-1.41421356j])
However, suppose you want a polynomial of type:
f(x) = a*(x-x0)**0 + b(x-x0)**1 + ... + n(x-x0)**n
Is there a simple way to construct a numpy.poly1d type function
and find the roots ? I've tried scipy.fsolve but it is very unstable as it depends highly on the choice of the starting values
in my particular case.
Thanks in advance
Best Regards
rrrak
EDIT: Changed "polygon"(wrong) to "polynomial"(correct)
First of all, surely you mean polynomial, not polygon?
In terms of providing an answer, are you using the same value of "x0" in all the terms? If so, let y = x - x0, solve for y and get x using x = y + x0.
You could even wrap it in a lambda function if you want. Say, you want to represent
f(x) = 1 + 3(x-1) + (x-1)**2
Then,
>>> g = numpy.poly1d([1,3,1])
>>> f = lambda x:g(x-1)
>>> f(0.0)
-1.0
The roots of f are given by:
f.roots = numpy.roots(g) + 1
In case x0 are different by power, such as:
f(x) = 3*(x-0)**0 + 2*(x-2)**1 + 3*(x-1)**2 + 2*(x-2)**3
You can use polynomial operation to calculate the finally expanded polynomial:
import numpy as np
import operator
ks = [3,2,3,2]
offsets = [0,2,1,2]
p = reduce(operator.add, [np.poly1d([1, -x0])**i * c for i, (c, x0) in enumerate(zip(ks, offsets))])
print p
The result is:
3 2
2 x - 9 x + 20 x - 14

Categories

Resources