I want to evaluate the sum
using Python and SymPy, I'm relatively new using SymPy and the first thing I tried was
from sympy import exp, oo, summation, symbols
n, x = symbols('n,x')
summation(exp(-n*x), (n, 1, oo))
But it doesn't work, it just returns the unevaluated sum.
I can make it work using
from sympy import exp, oo, summation, symbols
n, x = symbols('n,x')
f = exp(-x)
summation(x**(-n), (n, 1, oo)).subs(x,f)
But I would like to know if it is possible to make it work without need to break the expression into x^n and then substitute x by e^-x.
Thank you
Try using the following:
x , n = smp.symbols('x n')
smp.Sum(smp.exp(-n*x),(n, 1, smp.oo))
Related
I am using sympy to derive some equations and I experience some unexpected behaviour with substituting. Let's say I have a function f(x) that I differentiate by x like this:
fx = f(x).diff()
This results in the following:
Now if I substitute x with a value such as pi, like this:
fx.subs(x, pi)
I get:
However, if I substitute x with another variable, let say phi, like this:
fx.subs(x, phi)
I get something unexpected:
What is happening is that sympy is replacing x in the equation before differentiating, I would like that it does after it. I have seen some suggestions that I should use .doit(), but that does not result in a wanted solution:
fx.doit().subs(x, phi)
What am I doing wrong and how can I replace the variable after the differentiation?
Use srepr to see the structure of an expression more directly:
In [48]: f(x).diff(x).subs(x, pi)
Out[48]:
⎛d ⎞│
⎜──(f(x))⎟│
⎝dx ⎠│x=π
In [49]: srepr(f(x).diff(x).subs(x, pi))
Out[49]: "Subs(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))), Tuple(Symbol('x')), Tuple(pi))"
So you can see that Subs is what is used to represent an unevaluated substitution:
In [50]: Subs(f(x).diff(x), x, phi)
Out[50]:
⎛d ⎞│
⎜──(f(x))⎟│
⎝dx ⎠│x=φ
Then doit is used to make the Subs evaluate (by performing the substitution):
In [51]: Subs(f(x).diff(x), x, phi).doit()
Out[51]:
d
──(f(φ))
dφ
https://docs.sympy.org/latest/modules/core.html#subs
according to this graph: desmos
print(solve('x**2 + x - 1/x'))
# [-1/3 + (-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3) + 1/(9*(-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)), -1/3 + 1/(9*(-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)) + (-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3), -1/3 + 1/(9*(sqrt(69)/18 + 25/54)**(1/3)) + (sqrt(69)/18 + 25/54)**(1/3)]
I was expecting [0.755, 0.57], but, I got something I cannot use in my future program. I desire to get a list of floats as result, so refer to this post, I did following, but I got some even more weird:
def solver(solved, rit=3):
res = []
for val in solved:
if isinstance(val, core.numbers.Add):
flt = val.as_two_terms()[0]
flt = round(flt, rit)
else:
flt = round(val, rit)
if not isinstance(flt, core.numbers.Add):
res.append(flt)
return res
print(solver(solve('x**2 + x - 1/x')))
# [-0.333, -0.333, -0.333]
Now I am really disappointed with sympy, I wonder if there is an accurate way to get a list of floats as result, or I will code my own gradient descent algorithm to find the roots and intersection.
sym.solve solves an equation for the independent variable. If you provide an expression, it'll assume the equation sym.Eq(expr, 0). But this only gives you the x values. You have to substitute said solutions to find the y value.
Your equation has 3 solutions. A conjugate pair of complex solutions and a real one. The latter is where your two graphs meet.
import sympy as sym
x = sym.Symbol('x')
# better to represent it like the equation it is
eq = sym.Eq(x**2, 1/x - x)
sol = sym.solve(eq)
for s in sol:
if s.is_real:
s = s.evalf()
print(s, eq.lhs.subs({x: s})) # eq.rhs works too
There are a variety of things you can do to get the solution. If you know the approximate root location and you want a numerical answer, nsolve is simplest since it has no requirements on the type of expression:
>>> from sympy import nsolve, symbols
>>> x = symbols('x')
>>> eq = x**2 + x - 1/x
>>> nsolve(eq, 1)
0.754877666246693
You can try a guess near 0.57 but it will go to the same solution. So is there really a second real roots? You can't use real_roots on this expression because it isn't in polynomial form. But if you split it into numerator and denominator you can check for the roots of the numerator:
>>> n, d = eq.as_numer_denom()
>>> from sympy import real_roots
>>> real_roots(n)
[CRootOf(x**3 + x**2 - 1, 0)]
So there is only one real root for that expression, the one that nroots gave you.
Note: the answer that solve gives is an exact solution to the cubic equation and it can't figure out definitively which ones are a solution to the equation so it returns all three. If you evaluate them you will find that only one of them is real. But since you don't need the symbolic solution, just stick to nroots.
I'm writing software which uses SymPy to symbolically write code, and I've encountered multiplied sums that I need to simplify. The algorithm I'm using calls for the use of the Cauchy product to convert two sums multiplied by each other into a double sum. Below is an example of what I'm trying to accomplish:
from sympy import Sum, Function, Symbol, oo
# Define variables
n = Symbol('n')
x = Symbol('x')
t = Symbol('t')
# Define functions
theta = Function('theta')(t)
p = Function('p')(n,x)
q = Function('q')(n,x)
# Create Summations
pSum = Sum(p*theta**n, (n,0,oo))
qSum = Sum(q*theta**n, (n,0,oo))
# Multiply
out = pSum * qSum
print(out)
>>> Sum(p(n, x)*theta(t)**n, (n, 0, oo))*Sum(q(n, x)*theta(t)**n, (n, 0, oo))
I need to convert this to
print(out)
>>> Sum(Sum((p(i, x)*q(n-i, x))*theta**n, (i, 0, n)), (n, 0, oo))
My approach at this was importing Sum and defining a class that inherits from Sum. I then define the __mul__ operator to do what I want. This works for simple cases, but in more complicated cases, it won't work. In this example, the first case works, but the next one won't multiply because the * isn't calling __mul__ when already in SymPy.
import sympy
from sympy import expand, Function, Symbol, oo, diff, Sum, Derivative
class Sum2(Sum):
# Overriding the __mul__ method.
def __mul__(self, other):
if isinstance(other, Sum2):
i = Symbol('i')
n = Symbol('n')
return Sum2(Sum(self.args[0].subs(n, i)*other.args[0].subs(n, n-i), (i,0,n)), (n,0,oo))
else:
super().__mul__(other)
x = Symbol('x')
t = Symbol('t')
n = Symbol('n')
f = Function('f')(n, x)
a = Sum2(f*t**n, (n,0,oo))
# Works
print(a*a)
# Doesn't work.
c = (Derivative(a,x)*a).doit()
print(c)
print(c.doit())
print(expand(c))
I've tried a similar approach, inheriting from Function instead. Same problem. Perhaps __mul__ wasn't the right function to redefine? How can I allow infinite sums to be multiplied in this way?
I am trying to calculate some polynomials given an input numerator and denominator polynomials as coefficient arrays.
How can I create my polynomials from these arrays?
E.g:
Inputs:
den= [2,3,4]
num= [1,3]
Output:
(s+3)/(s^2+3*s+4)
I need to use symbols because I will further need to divide the results by other polynomials and perform further polynomial computations.
P.S Is sympy suitable for this? I would usually solve things like this in matlab but I want to expand my knowledge.
You can do the following:
den = [2, 3, 4]
num = [1, 3]
x = symbols('x')
Poly(num, x)/Poly(den, x)
This creates Poly objects for the numerator and denominator (not just expressions). The coefficients are listed from the highest power of x.
Note that the result of division is an ordinary expression, since there is no RationalFunction type in SymPy. If you want to apply the tools from the polys module to the numerator and denominator, keep them separate as a tuple.
I think what you want is (s+3)/(2*s^2+3*s+4), there is a typo in your original expression. And in Python, ^ is not power, power is **.
You just need a ordinary Python list comprehension:
from sympy import poly
from sympy.abc import s
den_ = sum(co*s**i for i, co in enumerate(reversed(den)))
num_ = sum(co*s**i for i, co in enumerate(reversed(num)))
res = num_/den_
I'm trying to code various optimisation methods, as a way of revising. I want to be able to use SymPy to evaluate a function with an arbitrary number of variables at a given point, where the co-ordinates of the point are stored in an array.
For example, I'd like to evaluate f(x,y) = 3*x**2 - 2*x*y + y**2 + 4*x + 3*y at the point b = [1,2]. But I'd really like a general way of doing it, that can handle a function with any number of variables and an appropriate length array as the point to be evaluated as, so sympy.evalf(f, subs = {foo}) isn't really very useful.
You are working with SymPy expression trees, not functions. On any expression you can do:
>>> vars = sorted(expression.free_symbols)
>>> evaluated = expression.subs(*zip(vars, your_values))
I would also expect this to be easier to do, but here's a good workaround:
If you know the symbol names ('x','y', e.g.), you can create a dict on the fly using zip:
fvars = sympy.symbols('x, y') #these probably already exist, use: fvars = [x,y]
b = [1,2]
sympy.evalf(f, subs = dict(zip(fvars,b)))
lambdify is a good option to generate a Python-callable function.
An example, assuming you have a function f and the symbols x and y:
from sympy import lambdify
import numpy as np
callable_fct = lambdify((x, y), f)
xn = np.arange(0, 2, 0.1)
yn = 3
print(callable_fct(xn, yn))