Using Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56)
[GCC 7.2.0] on linux
Trying to see if sympy can solve $y'(x)^2 = y(x)$. The general solution can be easily solved by hand. But sympy gives [] for solution.
Did I type something wrong? Is there a trick to make sympy solve this?
>>> from sympy import *
>>> y = Function('y')
>>> x = symbols('x')
>>> dsolve( Eq( Derivative(y(x),x)**2 , y(x) ), y(x))
[]
Maple gives both the singular and general solution
ode:=( diff(y(x),x))^2=y(x);
dsolve( ode,y(x));
Mathematica gives the general solution only
ode=(y'[x])^2==y[x]
DSolve[ode,y[x],x]
Can sympy solve this ODE?
The methods implemented in SymPy focus on the ODEs in which the highest derivative of the unknown appears on its own, not inside of some function. Once the ODE is rewritten as y'(x) = (+ or -) sqrt(y(x)), SymPy solves it.
>>> dsolve(Eq(Derivative(y(x), x), sqrt(y(x))), y(x))
Eq(y(x), C1**2/4 + C1*x/2 + x**2/4)
>>> dsolve(Eq(Derivative(y(x), x), -sqrt(y(x))), y(x))
Eq(y(x), C1**2/4 - C1*x/2 + x**2/4)
This reduction can be done automatically with solve, starting with the original form of the equation:
rhs = solve(Eq(Derivative(y(x), x)**2, y(x)), Derivative(y(x), x))
[dsolve(Eq(Derivative(y(x), x), r), y(x)) for r in rhs]
Related
I have an equation: f = (100*E**(-x*1600)-50), it takes a very long time to give a solution for x but in another online solver, it only takes a few ms. How can I do to boost the performance?
raw code:
f = (100*E**(-x*1600)-50)
solve(f,x)
Expected result:
If you just want the real solution (and not the many symbolic solutions) use nsolve. The bisect solvers is appropriated for this function with a steep gradient near the root. Defining lam = var('lam') gives
If you want a symbolic solution (but not the many imaginary ones) then solveset or the lower level _invert can be used:
>>> from sympy import solveset, var, Reals
>>> from sympy.solvers.solvers import _invert
>>> var('x')
x
>>> eq=(100*E**(-x*1600)-50)
>>> solveset(eq,x,Reals)
{log(2)/1600}
>>> from sympy.solvers.solvers import _invert
>>> _invert(eq,x)
(log(2)/1600, x)
I have a simple equation, trying to solve for using symbolic, however the code gets stuck and I do not get an error for me to debug. How can I do this correctly?
from sympy import *
from sympy import init_printing
init_printing(use_latex = True)
import sympy as sp
from numpy import random
import numpy as np
import math
from decimal import *
timeS = symbols("t")
eq1 = Eq( (-4221.4125*exp(-2750.0*timeS)*sin(6514.4071*timeS) + 10000.0*exp(-2750.0*timeS)*cos(6514.4071*timeS)),8000)
T_off = solve(eq1, timeS )[0]
display("T_off = ",T_off)
Your equation looks like one that doesn't have an analytic solution so you should use nsolve instead. There is a root between -0.001 and 0 so the bisect method gives:
In [59]: nsolve(eq1, timeS, [-0.001, 0])
Out[59]: 3.46762014687136e-5
This is an ill-posed equation. Rescale by dividing both sides by 10**4 and replace timeS with Symbol(x)/10**4 and use nsolve
>>> eq2 = eq1.func(eq1.lhs/10**4, eq1.rhs/10**4).subs(timeS, symbols('x')/10**4)
>>> from sympy import nsolve
>>> nsolve(eq2,0)
0.346762014687135
So timeS ~= 0.35e-4. The sqrt function automatically scales sums so sqrt(eq1.rewrite(Add)) will reduce coefficients of the terms to something less than 1 but such simplification is not part of SymPy simplification of general epxressions at present.
For a project i am working on i need the derivative of a function against wrt cos(theta) but when using Sympy v1.5.1 get an error message stating non-symbols cannot be used as a derivative. This was no problem up to Sympy v1.3 but later versions give this error.
>>> l=1
>>> theta = symbols('theta')
>>> eq=diff((cos(theta)**2-1)**l,cos(theta),l)
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/base/data/home/apps/s~sympy-live-
hrd/20200105t193609.423659059328302322/sympy/sympy/core/function.py", line 2446, in diff
return f.diff(*symbols, **kwargs)
File "/base/data/home/apps/s~sympy-live-
hrd/20200105t193609.423659059328302322/sympy/sympy/core/expr.py", line 3352, in diff
return Derivative(self, *symbols, **assumptions)
File "/base/data/home/apps/s~sympy-live-
hrd/20200105t193609.423659059328302322/sympy/sympy/core/function.py", line 1343, in __new__
__)))
ValueError:
Can't calculate derivative wrt cos(theta).
According to the Sympy documentation (https://docs.sympy.org/latest/modules/core.html#sympy.core.function.Derivative) i may be able to solve this using:
>>> from sympy.abc import t
>>> F = Function('F')
>>> U = f(t)
>>> V = U.diff(t)
>>> direct = F(t, U, V).diff(U)
Unfortunately i can't get this to work with this equation in Sympy v1.5.1.
Suggestions/help are much appreciated.
derivative of a function against wrt cos(theta)
Did this really work before in sympy? i.e. you were able to differentiate w.r.t cos(theta)? This should not work as differentiation is w.r.t to a symbol. For example Maple also gives error
diff( 1+cos(theta)^2,cos(theta))
Error, invalid input: diff received cos(theta), which is not valid for its 2nd argument
Strange that Mathematica does allow this. But I think this is not good behavior. May be that is why sympy no longer allows it.
But you can do this in sympy
from sympy import *
theta,x = symbols('theta x')
eq = (cos(theta)**2-1)**2
result = diff( eq.subs(cos(theta),x) ,x)
result.subs(x,cos(theta))
Which gives
4*(cos(theta)**2 - 1)*cos(theta)
In Mathematica (which allows this)
D[(Cos[theta]^2 - 1)^2, Cos[theta]]
gives
4 Cos[theta] (-1 + Cos[theta]^2)
Perhaps SymPy over-corrected. If the expression has a single generator matching the function of interest then the substitution-equivalent differentiation could take place. Cases which shouldn't (probably) be allowed are (x + 1).diff(cos(x)), sin(x).diff(cos(x)), etc... But (cos(x)**2 - 1).diff(cos(x)) should (probably) be ok. As #Nasser has indicated, a simple substitution/differentiation/backsubstitution will work.
I have an equation, as follows:
R - ((1.0 - np.exp(-tau))/(1.0 - np.exp(-a*tau))) = 0.
I want to solve for tau in this equation using a numerical solver available within numpy. What is the best way to go about this?
The values for R and a in this equation vary for different implementations of this formula, but are fixed at particular values when it is to be solved for tau.
In conventional mathematical notation, your equation is
The SciPy fsolve function searches for a point at which a given expression equals zero (a "zero" or "root" of the expression). You'll need to provide fsolve with an initial guess that's "near" your desired solution. A good way to find such an initial guess is to just plot the expression and look for the zero crossing.
#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve
# Define the expression whose roots we want to find
a = 0.5
R = 1.6
func = lambda tau : R - ((1.0 - np.exp(-tau))/(1.0 - np.exp(-a*tau)))
# Plot it
tau = np.linspace(-0.5, 1.5, 201)
plt.plot(tau, func(tau))
plt.xlabel("tau")
plt.ylabel("expression value")
plt.grid()
plt.show()
# Use the numerical solver to find the roots
tau_initial_guess = 0.5
tau_solution = fsolve(func, tau_initial_guess)
print "The solution is tau = %f" % tau_solution
print "at which the value of the expression is %f" % func(tau_solution)
You can rewrite the equation as
For integer a and non-zero R you will get a solutions in the complex space;
There are analytical solutions for a=0,1,...4(see here);
So in general you may have one, multiple or no solution and some or all of them may be complex values. You may easily throw scipy.root at this equation, but no numerical method will guarantee to find all the solutions.
To solve in the complex space:
import numpy as np
from scipy.optimize import root
def poly(xs, R, a):
x = complex(*xs)
err = R * x - x + 1 - R
return [err.real, err.imag]
root(poly, x0=[0, 0], args=(1.2, 6))
sympy does not find the two real roots of this rather straightforward equation:
import sympy
x = Symbol('x')
solve(-2*x**2*exp(1 - x**2) + exp(1 - x**2),x)
Returns "[oo]"
Is this a bug or is my command ill formed ?
Thanks!
Markus
It seems to work fine for me, so perhaps you just need to upgrade?
>>> from sympy import Symbol, solve, exp
>>> x = Symbol('x')
>>> solve(-2*x**2*exp(1 - x**2) + exp(1 - x**2),x)
[-sqrt(2)/2, sqrt(2)/2]
>>> sympy.__version__
'0.7.2-git'