NotImplementedError in Sympy's solve - python

I'm reading an article about Bloom filters, https://en.wikipedia.org/wiki/Bloom_filter, in which an expression is derived for the optimal number of hash functions. I'd like to reproduce the computation for the simplified case that m = n, that is, I'd like to determine the minimum of the function
(1-exp(-x))**x
which, from the article, should occur at x = ln(2). I tried doing this with sympy as follows:
In [1]: from sympy import *
In [2]: x, y, z = symbols('x y z')
In [3]: init_printing(use_unicode=True)
In [8]: from sympy.solvers import solve
In [9]: solve(diff((1-exp(-x))**x,x), x)
However, I get a
NotImplementedError: multiple generators [x, exp(x), log(1 - exp(-x))]
No algorithms are implemented to solve equation x*exp(-x)/(1 - exp(-x)) + log(1 - exp(-x))
I would just like to double-check whether Sympy really cannot solve this problem? Perhaps I need to add additional constraints/assumptions on x?

When you run into this issue where an equation can't be solved by manipulation of symbols (solving analytically), it's possible that it can still be solved by trying different numbers and getting to (or very close to) the correct answer (solving numerically).
You can convert your sympy solution to a numpy-based function, and use scipy to solve numerically.
from sympy import lambdify
from scipy.optimize import fsolve
func_np = sp.lambdify(x, diff((1-exp(-x))**x,x), modules=['numpy'])
solution = fsolve(func_np, 0.5)
This solves the equation as 0.69314718, which is what you expect.

Related

How to solve separable differential equation using Sympy?

I cannot figure out how to solve this separable differential equation using sympy. Help would be greatly appreciated.
y′=(y−4)(y−2),y(0)=5
Here was my attempt, thanks in advance!!!
import sympy as sp
x,y,t = sp.symbols('x,y,t')
y_ = sp.Function('y_')(x)
diff_eq = sp.Eq(sp.Derivative(y_,x), (y-4)*(y-2))
ics = {y_.subs(x,0):5}
sp.dsolve(diff_eq, y_, ics = ics)
the output is y(x) = xy^2 -6xy +8x + 5
The primary error is the introduction of y_. This makes the variable y a constant parameter of the ODE and you get the wrong solution.
If you correct this you get an error of "too many solutions for the integration constant". This is a bug caused by not simplifying the integration constant after it first occurs. So multiplication and addition of constants should just be absorbed, an additive constant in an exponent should become a multiplicative factor for the exponential. As it is, exp(2*C_1)==3 has two solutions if C_1 is considered as an angle (it's a bit of tortured logic from computing roots in the complex plane).
The newer versions can actually solve this fully if you give the third hint in the classification list 'separable', '1st_exact', '1st_rational_riccati', ... that does something different than partial fraction decomposition of the first two
from sympy import *
x = Symbol('x')
y = Function('y')(x)
dsolve(Eq(y.diff(x), (y-2)*(y-4)),y,
ics={y.subs(x,0):5},
hint='1st_rational_riccati')
returning
\displaystyle y{\left(x \right)} = \frac{2 \cdot \left(6 - e^{2 x}\right)}{3 - e^{2 x}}

Is there a way to plot a function which is a partial derivate of a function with 2 variables in python?

I am using sympy to get the partial derivative of a function with two variables. This is what I have been trying but I am getting an error of using the same variable.
from sympy.plotting import *
import numpy as np
x=symbols('x')
y=symbols('y')
diff((cos(x))*cos(y)*(exp((-x)**2))*(exp((-y)**2)), x)
f=diff((cos(x))*cos(y)*(exp((-x)**2))*(exp((-y)**2)), x)
p1=plot(f,show=False)
p1
p1.show()
I'm not super familiar with sympy but it seems cool and this looked like a good starting point. From what I can tell you some extraneous code. Here is how I refactored it (using import * out of sheer laziness and not knowing what else you might want to do):
from sympy import *
x, y = symbols('x y')
f=diff((cos(x))*cos(y)*(exp((-x)**2))*(exp((-y)**2)), x)
derivative_f = f.diff(x)
derivative_f
Which gives you a very pretty:
4𝑥2𝑒𝑥2𝑒𝑦2 cos(𝑥)cos(𝑦) − 4𝑥𝑒𝑥2𝑒𝑦2 sin(𝑥)cos(𝑦)+𝑒𝑥2𝑒𝑦2 cos(𝑥)cos(𝑦)

How to solve nonlinear equations using a for loop in python?

I am trying to solve for non linear equations in python. I have tried using the solver of the Sympy but it doesn't seem to work in a for loop statement. I am tyring to solve for the variable x over a range of inputs [N].
I have attached my code below
import numpy as np
import matplotlib.pyplot as plt
from sympy import *
f_curve_coefficients = [-7.14285714e-02, 1.96333333e+01, 6.85130952e+03]
S = [0.2122, 0, 0]
a2 = f_curve_coefficients[0]
a1 = f_curve_coefficients[1]
a0 = f_curve_coefficients[2]
s2 = S[0]
s1 = S[1]
s0 = S[2]
answer=[]
x = symbols('x')
for N in range(0,2500,5):
solve([a2*x**2+a1*N*x+a0*N**2-s2*x**2-s1*x-s0-0])
answer.append(x)
print(answer)
There could be more efficient ways of solving this problem than using sympy * any help will be much appreicated.
Note I am still new to python, after transisitioning from Matlab. I could easliy solve this problem in Matlab and could attach the code, but I am battiling with this in Python
Answering to your question "There could be more efficient ways of solving this problem than using sympy * "
you can use fsolve to find the roots of non linear equation:
fsolve returns the roots of the (non-linear) equations defined by func(x) = 0 given a starting estimate
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html
below is the code:
from scipy.optimize import fsolve
import numpy as np
def f(variables) :
(x,y) = variables
first_eq = 2*x + y - 1
second_eq = x**2 + y**2 - 1
return [first_eq, second_eq]
roots = fsolve(f, (-1 , -1)) # fsolve(equations, X_0)
print(roots)
# [ 0.8 -0.6]
print(np.isclose(f(roots), [0.0, 0.0])) # func(root) should be almost 0.0.
If you prefer sympy you can use nsolve.
>>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1])
[0.620344523485226]
[1.83838393066159]
The first argument is a list of equations, the second is list of variables and the third is an initial guess.
Also For details, you can checkout similar question asked earlier on stack overflow regarding ways to solve Non-linear equations in python:
How to solve a pair of nonlinear equations using Python?
According to this documentation, the output of solve is the solution. Nothing is assigned to x, that's still just the symbol.
x = symbols('x')
for N in range(0,2500,5):
result = solve(a2*x**2+a1*N*x+a0*N**2-s2*x**2-s1*x-s0-0)
answer.append(result)

How to solve complex equations in python?

I want to solve the equation in python:
x+conj(x)=2
x-conj(x)=4
Then, ovbiously x is 1+2i.
In python, I am using sympy and lumpy package like this.
BUT! there is no outcome. just blanket came up.
What should I do to solve these equations in python?
You really can't mix numpy and sympy expressions. Numpy doesn't understand sympy's functions nor symbols, and vice versa sympy doesn't understand about unevaluated numpy functions.
Therefore, you need to write everything with sympy functions.
Note that your system of equations doesn't have a solution. For example in the second equation (x-conj(x)) gives 4i for x=1+2i.
Unfortunately, sympy doesn't work very well with this type of equations. A straightforward way to write them, would be:
from sympy import symbols, Eq, conjugate, solve, I, re, im
x = symbols('x')
solve([Eq(x + conjugate(x), 2), Eq(x - conjugate(x), 4*I)])
which wrongly gives no solution.
Some experimenting does give a way to write the equations and get the expected outcome:
xc = re(x) - I * im(x)
solve([Eq(x + xc, 2), Eq(x - xc, 4 * I)])
Output: [{x: 1 + 2*I, re(x): 1, im(x): 2}]

Use sympy to solve a transcendental equation

Experienced with Python. New to Sympy.
I have a transcendental equation, f(x) = sin(x) - x.
If y = f(x), I want to solve for x knowing y.
I think Sympy can do this, but I have no experience with it. Can someone explain what I should do?
(The question Transcendental Equation has answers for hand-rolling the iterative approach, which is my back-up.)
Here is what I have tried:
from sympy import *
x = symbols('x')
solve(Eq(sin(x) - x)) # Exception raised here
# NotImplementedError: multiple generators [x, sin(x)]
# No algorithms are implemented to solve equation -x + sin(x)
I recognize this does not even communicate that I have a known value for y. As you can see, I don't understand what to do at all.
This would be an iterative solution. Is there a way to get sympy to do this, or should I be using a different Python package for iterative solutions?
All help is appreciated.
What about using nsolve? ie:
>>> from sympy import *
>>> x = symbols('x')
>>> nsolve(sin(x)-x, x, 1)
It seems it uses mpmath.findroot behind the curtains.

Categories