How to solve an equation that contains Sum in SymPy? - sympy

I want to solve the following equation for x with SymPy:
(Note that the equation can be simplified as mentioned in the comments, I copied it verbatim from an example in a legal document.)
According to my understanding, this translates to the following SymPy expression:
from sympy import Sum, solve
from sympy.abc import k, x
solve(350 - 18500 + Sum(182.94 * (1/(1+x)**(k/12)), (k, 1, 120)), x)
However, when I run this, the result is empty:
[]
What am I doing wrong?

solve probably shouldn't give [] but you will get better results from nsolve for this expression using a guess for x near 0:
>>> from sympy.abc import k, x
>>> from sympy import nsolve
eq = 350 - 18500 + Sum(182.94 * (1/(1+x)**(k/12)), (k, 1, 120))
>>> nsolve(eq, 0)
0.0397546543274819
>>> eq.subs(x,_).round(2)
0

Related

sympy solve( ) with complex numbers

I have a hard time getting sympy to work with complex numbers.
Take the following example:
from sympy import *
x = Symbol("x")
expr = sqrt(x) # note that this is imaginary for x<0
# Find all solutions such that |expr| < 1
print( solve( abs(expr)<1, x ) )
This, however, only finds 0<=x<1.
It misses the negative x region -1<x.
How can I make this work?
Since abs(sqrt(x)) = sqrt(x**2) for real numbers, you could solve sqrt(x**2)<1 instead.
>>> solve(sqrt(x**2)<1)
(-1 < x) & (x < 1)
You can perhaps find the boundaries of the solution by replacing your argument of the sqrt with a negative or nonnegative symbol:
>>> solve(abs(sqrt(n))-1)
[-1]
>>> var('nn',nonnegative=1)
nn
>>> solve(abs(sqrt(nn))-1)
[1]
Could you get the boundaries numerically?
>>> [nsolve((abs(x**2+2*x-sqrt(x+5)))-1,i) for i in (-3,-1,0,1)]
[-2.86080585311170, 0.533751168755204, 0.533751168755204, 1.11490754147676]

Simplification in sympy

I am new to sympy, and I cannot understand why the result of the following piece of code does not results in f(x)=0
from sympy import *
f = Function('f')
x = Symbol('x')
simplify(Eq(f(x)+1,1))
When SymPy rewrites x + x as 2*x that is automatic rewriting. Not everything is automatic, however, as you have seen. If you want to know what value of f(x) makes that Equality true, you can solve for it:
>>> solve(Eq(f(x) + 1, 1), f(x))
[0]

how to use SymPy or other library to have a numerical solution

I was trying to solve two equations for two unknown symbols 'Diff' and 'OHs'. the equations are shown below
x = (8.67839580228369e-26*Diff + 7.245e-10*OHs**3 +
1.24402291559836e-10*OHs**2 + OHs*(-2.38073807380738e-19*Diff -
2.8607855978291e-18) - 1.01141409254177e-29)
J= (-0.00435840284294195*Diff**0.666666666666667*(1 +
3.64525434266056e-7/OHs) - 1)
solution = sym.nsolve ((x, J), (OHs, Diff), (0.000001, 0.000001))
print (solution)
is this the correct way to solve for the two unknowns?
Thanks for your help :)
Note: I edited your equation per Vialfont's comments.
I would say it is a possible way but you could do better by noticing that the J equation can be solved easily for OHs and substituted into the x equation. This will then be much easier for nsolve to solve:
>>> osol = solve(J, OHs)[0] # there is only one solution
>>> eq = x.subs(OHs,osol)
>>> dsol = nsolve(eq, 1e-5)
>>> eq.subs(Diff,dsol) # verify
4.20389539297445e-45
>>> osol.subs(Diff,dsol), dsol
(-2.08893263437131e-12, 4.76768525775849e-5)
But this is still pretty ill behaved in terms of scaling...proceed with caution. And I would suggest writing Diff**Rational(2,3) instead of Diff**0.666666666666667. Or better, then let Diff be y**3 so you are working with a polynomial in y.
>>> y = var('y', postive=True)
>>> yx=x.subs(Diff,y**3)
>>> yJ=J.subs(Diff,y**3)
>>> yosol=solve(yJ,OHs)[0]
>>> yeq = yx.subs(OHs, yosol)
Now, the solutions of eq will be where its numerator is zero so find the real roots of that:
>>> ysol = real_roots(yeq.as_numer_denom()[0])
>>> len(ysol)
1
>>> ysol[0].n()
0.0362606728976173
>>> yosol.subs(y,_)
-2.08893263437131e-12
That is consistent with our previous solution, and this time the solutions in ysol were exact (given the limitations of the coefficients). So if your OHs solution should be positive, check your numbers and equations.
Your expressions do not meet Sympy requirements, including the exponential expressions. May be it is easier to start with a simpler system to solve with two unknowns and only a square such as:
from sympy.abc import a,b,x, y
from sympy import solve,exp
eq1= a*x**2 + b*y+ exp(0)
eq2= x + y + 2
sol=solve((eq1, eq2),(x,y),dict=True)
sol includes your answers and you have access to solutions with sol[0][x] and sol[0][y]. Giving values to the parameters is done with the .sub() method:
sol[0][x].subs({a:1, b:2}) #gives -1
sol[0][y].subs({a:1, b:2}) #gives -1

Sympy Solve returning type error?

I have written a program to solve a transcendental equation using Sympy Solvers, but I keep getting a TypeError. The code I have written is the following:
from sympy.solvers import solve
from sympy import Symbol
import sympy as sp
import numpy as np
x = Symbol('x',positive=True)
def converts(d):
M = 1.0
res = solve(-2*M*sp.sqrt(1+2*M/x)-d,x)[0]
return res
print converts(0.2)
which returns the following error:
raise TypeError('invalid input: %s' % p)
TypeError: invalid input: -2.0*sqrt(1 + 2/x)
I've solved transcendental equations this way before, but this is the first time I'm facing this error.
From what I gather, it looks like Sympy is seeing my input as a string instead of a rational number, but I'm not sure if or why it is so. Can someone please tell me why I'm getting this error and/or how to fix it?
Edit: I've rewritten my code to make it clearer but the result is still the same
This is the equation I'm trying to solve
Let's first recreate the actual equation.
from sympy import *
init_printing()
M, x, d = symbols("M, x, d")
eq = Eq(-2*M * sqrt(1 + 2*M/x) - d, 0)
eq
As in your code, we can substitute values: M=1, d=0.2
to_solve = eq.subs({M:1, d:0.2})
to_solve
Now, we may attempt to solve it directly
solve(to_solve, x)
Unfortunately, solve fails to find the solution in this case. If we take a closer look at the equation, the square root part should return a negative number for this equation to be valid.
-2 * (-1/10) - 0.2 = 0
As square root of a number can not be negative, correct me if I'm wrong, sympy is unable to find a value for x such that sqrt(1+2/x) == -1/10
This problem is due to our choice of values for d and M. Solution exists if M and d are of opposite signs.
to_solve = eq.subs({M:-1, d:0.2})
to_solve
solve(to_solve, x)
[2.02020202020202]
Run this code on sympy live and experiment with other values.

sympy differential equality

I'm trying to setup sympy to calculate derivatives. When I test it with simple equation, I'm finding the same answer (equality is true between sympy calculation and my own calculation). However when I try with more complicated ones, when it doesnt work (I checked answers with wolfram alpha too).
Here is my code:
from __future__ import division
from sympy import simplify, cos, sin, expand
from sympy import *
x, y, z, t = symbols('x y z t')
k, m, n = symbols('k m n', integer=True)
f, g, h = symbols('f g h', cls=Function)
equation = (x**3*y-x*y**3)/(x**2+y**2)
equation2 = (x**4*y+4*x**2*y**3-y**5)/((x**2+y**2)**2)
pprint(equation)
print ""
pprint(equation2)
print diff(equation,x) == equation2
This is a common "gotcha" in Sympy. For creating symbolic equalities, you should use sympy.Eq and not = or == (see the tutorial). For your example,
Eq(equation.diff(x), equation2).simplify()
True
Note, as above, that you may have to call simplify() in order to see wheather the Eq object corresponds to True or False