from sympy import symbols, Eq, solve, sin, sqrt
x = symbols('x')
D = symbols('d')
C = symbols('c')
eq1 = 2*sin(x)+sqrt(1-sin^2(x))+D*sin(x/2)-sin(2*x)-1-C
sol = solve(eq1)
print(sol)
Actually in the equation eq1=0. And I was trying to find a function for x which I couldn't find by mathematics. So I was thinking if it is possible in Python. My friend was saying that we actually deal with numbers in Python so he said it would be good if he can get some value of x. In that equation C and D is constant. He was saying that they are height. So we can consider that C,D=1 to 1000 (we can choose whatever we wish). Is there really possible way to substitute that function to find a value of x?
You can use fsolve to numerically solve the non-linear equation. The subs attribute of a sympy expression can be used to substitute a value to a variable.
from sympy import symbols, Eq, solve, sin, sqrt
from scipy.optimize import fsolve
x = symbols('x')
D = symbols('d')
C = symbols('c')
eq1 = 2*sin(x)+sqrt(1-(sin(x))**2)+D*sin(x/2)-sin(2*x)-1-C
values = {
C: 500,
D: 1000
}
eq1_in_x = eq1.subs(values)
def f(y):
return float(eq1_in_x.subs(x,y[0]))
sol = fsolve(f,1) # Here, 1 is an initial guess.
print(sol)
Outout:
[1.04635456]
So, 1.04635456 is a value of x that satisfies the equation with C and D values being 500 and 1000, respectively.
Take a look at sympy tutorial: https://docs.sympy.org/latest/tutorial/index.html
also Itk this should solve your problem: With #Oscar Benjamin advice:
from sympy import nsolve, sin, sqrt
from sympy.abc import x, C, D
eq1 = 2*sin(x)+sqrt(1-sin(x)**2)+C*sin(x/2)-sin(2*x)-1-D
sol = nsolve(eq1.subs({C: C_value, D: D_value}, x0)
print(sol)
x0 is the initialization of x, depending on the value of x0 you can end with different value of x verifying eq = 0.
Related
I'm using Sympy 1.10.1 in Jupyter. Some cells look like:
import sympy as sp
x = sp.Symbol('x')
y = sp.Function('y')(x)
y.diff(x)
diff_eq = sp.Eq(y*y.diff(x), 4*x )
diff_eq
sol = sp.dsolve(diff_eq, y)
sol
And Sympy responds with
[Eq(y(x), -sqrt(C1 + 4*x**2)), Eq(y(x), sqrt(C1 + 4*x**2))]
Can I modify the above so that Sympy does not offer solutions
with negative range?
I am solving an ODE with Sympy. The equation is
ODE
To solve it, I used this little code, which returns this result.
from sympy import *
from numpy import *
import matplotlib.pyplot as plt
x = symbols('x')
y = Function('y')
f = y(x)
print(f)
edo = Eq(f.diff()+3*x**2*f, 6*x**2)
print(edo)
edoSolve = dsolve(edo, f)
print(edoSolve)
C1*exp(-x**3) + 2
My question is, how can I plot the result with x being a range from 0 to 10?
Firstly it's problematic to combine these two lines:
from sympy import *
from numpy import *
These two libraries define many functions with the same names and mixing those together will lead to problems. For clarity it is better to do something like:
import sympy as sym
import numpy as np
You can only plot a sympy expression if you give numbers for all of the symbols apart from the one that you want to plot against (i.e. x in this example). That means that you need to have a concrete value for the integration constant C1. You can get that by giving an initial conditions (ics) argument to dsolve. Also since dsolve returns an equation you need to choose a side of the equation as the expression that you want to plot. Having done that the sym.plot function will do precisely what you ask for:
In [10]: import sympy as sym
In [11]: sol = sym.dsolve(edo, f, ics={f.subs(x, 0): 1})
In [12]: sol
Out[12]:
3
-x
y(x) = 2 - ℯ
In [13]: sym.plot(sol.rhs, (x, 0, 10))
Out[13]: <sympy.plotting.plot.Plot at 0x7f346de1caf0>
If you want to show solutions for multiple values for C1 together, you could append plots:
from sympy import symbols, Function, Eq, dsolve, plot
x = symbols('x')
y = Function('y')
f = y(x)
edo = Eq(f.diff() + 3 * x ** 2 * f, 6 * x ** 2)
edoSolve = dsolve(edo, f)
plot1 = plot(show=False)
for c1 in range(-5, 6):
plotc1 = plot(edoSolve.subs('C1', c1).rhs, (x, 0, 10), show=False)
plot1.append(plotc1[0])
plot1.show()
from sympy import Symbol
from sympy.solvers import solveset
x = Symbol('x')
equation = x**2 - 2*x + 1
result = solveset(equation, x)
Here, result evaluates to FiniteSet(1).
Since this is a quadratic equation, there must be 2 roots.
But also, since the two roots are the same (1 in this case), the result returns it only once.
For the purpose of solving linear recurrences, I need to know the repeated roots, and how many times did each one of them repeat.
How to do that?
You can convert it into a polynomial and then use the roots function, which will return a dictionary that has the roots as keys and the multiplicities as values, like so:
from sympy import roots
poly = equation.as_poly()
roots(poly)
# returns {1: 2}
Unlike nroots, this works with polynomials with symbolic coefficients as well:
from sympy.abc import a, b, c
poly = (a * x ** 2 - 2 * sqrt(a * c) * x + c).as_poly(x)
roots(poly, x)
# returns {sqrt(a*c)/a: 2}
I try to solve an equation with solve from Sympy. But my approach doesn't work as desired.
My equation : 0.00622765954483725 = (x * 24.39 * 0.921107170819325) / 143860432.178345.
My code :
from sympy import symbols, solve
import numpy as np
x = symbols('x')
sol = solve((np.array([[x],[x]]) * np.array([[24.39],[293.6]]) * np.array([[0.921107170819325],[1]])) / np.array([[143860432.178345],[143860432.178345]]) - np.array([[0.00622765954483725],[0.0089267519953503]]))
I had success with a linear expression, but I have a DataFrame and I want to solve all data at the same time.
from sympy import symbols, solve
x = symbols('x')
sol = solve((x * 24.39 * 0.921107170819325) / 143860432.178345 - 0.00622765954483725)
Numpy doesn't understand about sympy's symbols, nor does sympy understand about numpy arrays. The only way to make them work together, is with sympy's lambdify which can convert a symbolic sympy expression to a numpy function. In your case, you first need to create a symbolic solution, lambdify it, and call it on your arrays:
from sympy import symbols, solve, Eq, lambdify
a, b, c, d = symbols('a b c d', real=True)
x = symbols('x')
sol = solve(Eq(x * a * b / c, d), x) # solve returns a list of solutions, in this case a list with just one element
np_sol = lambdify((a, b, c, d), sol[0]) # convert the first solution to a (numpy) function
# everything before is only sympy, everything from here is only numpy
import numpy as np
a_np = np.array([[24.39], [293.6]])
b_np = np.array([[0.921107170819325], [1]])
c_np = np.array([[143860432.178345], [143860432.178345]])
d_np = np.array([[0.00622765954483725], [0.0089267519953503]])
np_sol(a_np, b_np, c_np, d_np)
Result:
array([[39879.],
[ 4374.]])
This code only works for solving the differential equation v_equation if v(t) isn't squared. When I squared it it returned the error PolynomialDivisionFailed. Is there another way of doing this with Sympy or should I find a different python package for doing these sorts of calculations.
from sympy import *
from matplotlib import pyplot as plt
import numpy as np
m = float(raw_input('Mass:\n> '))
g = 9.8
k = float(raw_input('Drag Coefficient:\n> '))
f1 = g * m
t = Symbol('t')
v = Function('v')
v_equation = dsolve(f1 - k * (v(t) ** 2) - m * Derivative(v(t)), 0)
C1 = Symbol('C1')
C1_ic = solve(v_equation.rhs.subs({t:0}),C1)[0]
v_equation = v_equation.subs({C1:C1_ic})
func = lambdify(t, v_equation.rhs,'numpy')
From my experience with symbolic math packages, I would not recommend performing (symbolic) calculations using floating point constants. It is better to define equations using symbolic constants, perform calculations as far as possible, and then substitute with numerical values.
With this approach, Sympy can provide a solution for this D.E.
First, define symbolic constants. To aid calculations, note that we can provide additional information about these constants (e.g., real, positive, e.t.c)
import sympy as sp
t = sp.symbols('t', real = True)
g, k, m = sp.symbols('g, k, m', real = True, positive = True)
v = sp.Function('v')
The symbolic solution for the DE can be obtained as follows
f1 = g * m
eq = f1 - k * (v(t) ** 2) - m * sp.Derivative(v(t))
sol = sp.dsolve(eq,v(t)).simplify()
The solution sol will be a function of k, m, g, and a constant C1. In general, there will be two, complex C1 values corresponding to the initial condition. However, both values of C1 result in the same (real-valued) solution when substituted in sol.
Note that if you don't need a symbolic solution, a numerical ODE solver, such as Scipy's odeint, may be used. The code would be the following (for an initial condition 0):
from scipy.integrate import odeint
def fun(v, t, m, k, g):
return (g*m - k*v**2)/m
tn = np.linspace(0, 10, 101)
soln = odeint(fun, 0, tn, args=(1000, 0.2, 9.8))
soln is an array of samples v(t) corresponding to the tn elements