I have a complicated equation which is function of several variables and I want to manipulate like this example:
y = (x + a) / z
x = y*z - a
Is it possible to do this kind of manipulation matlab or python?
If there is possibility then please point out method or function to do this operation.
I tried following code in Sympy Shell:
x,y,z,a = symbols ('x y z a')
solve ( y = (x-a)/z, x)
I am getting following error:
Traceback (most recent call last):
File "<string>", line 1
SyntaxError: non-keyword arg after keyword arg
In Matlab you'd need the symbolic math toolbox (which I don't have so I can't test) and then you should be able to do use the solve function:
syms y x a z
solve(y == (x+a)/z, x)
I have NO experince with sympy but pretty sure based on the docs this is how you do it:
from sympy import solve, Poly, Eq, Function, exp
from sympy.abc import x, y, z, a
solve(y - (x+a)/z, x)
SymPy is a Python library, so your SymPy code needs to be valid Python. In Python, = is the assignment operator, which is why solve ( y = (x-a)/z, x) gives a SyntaxError. See http://docs.sympy.org/latest/gotchas.html#equals-signs.
To create an equality in SymPy use Eq, like solve(Eq(y, (x - a)/z, x), or use the fact that expressions in SymPy are assumed to be equal to zero, like solve(y - (x - a)/z, x).
Related
Given an expression, we can convert it into a function using sympy.lambdify. Similarly, given a function, we can convert it into an expression by evaluating it at symbol x. We would naturally expect that these two operations are inverses of each other. And, this expected behaviour is displayed when I use polynomial expressions. For example,
import sympy as sym
x = sym.symbols('x')
expr = 5*x**2 + 2*x + 3
f = sym.lambdify([x],expr)
f_expr = f(x)
print(expr == f_expr)
gives True as its output.
On the other hand, the following code does not run
import sympy as sym
x = sym.symbols('x')
expr = sym.sin(x)
f = sym.lambdify([x],expr)
f_expr = f(x)
print(expr == f_expr)
and throws the error "TypeError: loop of ufunc does not support argument 0 of type Symbol which has no callable sin method". Could you please explain why this is happening? My guess would be that sym.sin(x) does not return an "expression" analogous to 5x**2 + 2x + 3. But, I would like to understand it a bit better. Thanks in advance.
For a non-numeric object the lambdify code tries to do x.sin()
with making sure the sin function is from library sympy not numpy to avoid confusions.
you can try :
import sympy as sym
from sympy import sin
x = sym.symbols('x')
expr = sin(x)
# f = sym.lambdify(x,expr)
f = lambda x:sin(x)
f_expr = f(x)
print(expr == f_expr)
I want to integrate a max function by sympy in python. However, it seems sympy cannot deal with such a function with relational comparison.
import sympy
def func(x):
return max(x,0)
x = sympy.symbols(x)
sympy.integrate(func(x),(x,-1,1))
Run the above code, it gives the error info:
File "<ipython-input-11-2630b8af4afe>", line 2, in func
return max(x,0)
File "/Applications/anaconda/lib/python3.6/site-packages/sympy/core/relational.py", line 304, in __nonzero__
raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational
It seems sympy cannot deal with functions with comparison. It gives the same error when I try a piecewise function, which also includes a process of comparison.
SymPy uses uppercase and lowercase names to refer (often) to functions and classes. When you get a "truth value" error it means that something that could give a True or False answer didn't (like if x < 1: print('less than 1')). If x is a Symbol then x < 1 remains a Lt(x, 1) object.
In your case, the function max tried to compare x and 0 and it couldn't get True or False comparison. Use the Max object instead to see your integral evaluate:
>>> from sympy import Max
>>> from sympy.abc import x
>>> integrate(Max(x,0),(x,-1,1))
1/2
There are two problems:
The first parameter to sympy.symbols should be a string to represent the variable. For example: x = sympy.symbols('x').
max is a Python function. A sympy function should be used instead: sympy.Max
import sympy
def func(x):
return sympy.Max(0, x)
x = sympy.symbols('x')
sympy.integrate(func(x), (x, -1, 1))
Also piecewise functions can be integrated:
def func2(x):
return sympy.Piecewise((-x, x < 0), (x * x, x < 0.5), (x * x * x, True))
sympy.integrate(func2(x), (x, -1, 1)) # 0.776041666666667
I am trying to solve the equations like this,
from sympy.solvers import solve
from sympy import Symbol
import math
x = Symbol('x')
A, B = 1, 2
print(solve((x) + (A/math.sqrt(x**4)) - (B * math.exp(-x)), x))
Traceback (most recent call last):
File "C:\Users\****\Desktop\Python Stuff\****\***.py", line 7, in <module>
print(solve((x) + (A/math.sqrt(x**4)) - (B * math.exp(-x)), x))
File "C:\Users\****\AppData\Local\Programs\Python\Python37\lib\site-packages\sympy\core\expr.py", line 280, in __float__
raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
Why this is happening?
x is a sympy.Symbol, so you can't use it with normal math library functions because they don't know about sympy. Instead, use sympy functions like sympy.sqrt:
from sympy.solvers import solve
import sympy
x = sympy.Symbol('x')
A, B = 1, 2
print(solve((x) + (A / sympy.sqrt(x ** 4)) - (B * sympy.exp(-x)), x))
(This raises another exception, with sympy complaining that it doesn't have an algorithm to solve this problem -- if you have problems with that too, you should post separate question.)
PS: as pointed out in a comment, the actual error you're getting is from a different expression. You'll need to fix this throughout.
I read such a script:
add_numbers = lambda x, y: x+y
add_five = lambda y: add_numbers(5,y)
It derive a new function of one variable, add_five, that adds 5 to its argument:
from this point, introduced functools
In [9]: from functools import partial
In [10]: add_five = partial(add_numbers, 5)
In [11]: add_five(7)
Out[11]: 12
As a novice, I guess it can be easily achieved by
add_five = lambda y: 5+y
add_six = lambda y: 6+y
I am confused what's the benefit if not define add_five in a straighforward method?
The utility of partial is to easily create specialised versions of functions from a general definition.
The case of adding numbers can be illustrating here add_numbers is the general case.
from functools import partial
def add_numbers(x, y):
return x + y
add5 = partial(add_nums, 5)
Here add5 is a specialised case of add_numbers roughly equivalent to
def add5(x):
return add_numbers(x, 5)
Adding numbers is a very trivial example and does not show the utility of partial
The following is a simple example that may better show the utility of partial.
Consider writing a procedure to compute the square root of a number using the Babylonian method.
def square_root(x, tolerance, convergence_test):
y = 1
while not convergence_test(x, y, tolerance):
y = (y + x/y)/2
return y
For most numbers, the convergence test can simply check the difference between y squared and x is 0. Let's call this the absolute error of the estimate
def absolute_error(x, y, tolerance):
return abs(x - y**2) <= tolerance
For very large and small numbers, using absolute error of the estimate can lead to wrong answers for various reasons. In those cases, it is better to use the relative error:
def relative_error(x, y, tolerance):
return abs(x/(y**2) - 1) <= tolerance
With partial, we can easily create specialised functions for using the either absolute and relative error.
sqrt_rel_err = partial(square_root, convergence_test=relative_error)
sqrt_abs_err = partial(square_root, convergence_test=absolute_error)
Now using either is trivial
>>> sqrt_rel_err(2, 0.00001)
1.4142156862745097
>>> sqrt_abs_err(2, 0.00001)
1.4142156862745097
And for small numbers: we see using absolute error gives the wrong answer (especially when the tolerance is greater than the number we are trying to get the square root of)
>>> x = sqrt_abs_err(1e-6, 0.00001)
>>> x**2
4.4981362843183905e-06
Whilst the relative error method yields a more accurate answer.
>>> x = sqrt_rel_err(1e-6, 0.00001)
>>> x**2
1.0000003066033492e-06
say I want to print the equation g(x) in the form g(x) = x^2 *........
how do I do it? This is my first time using python
import numpy as np
import matplotlib.pyplot as plt
import math
from sympy.mpmath import *
f = lambda x: ((x^2)*math.exp(-x))
dfdx = lambda x: diff(f,x)
d2fdx2 = lambda x: diff(dfdx,x)
g = lambda x: ((math.exp(x)/math.factorial(2))*d2fdx2)
print(g)
(edit) the output im getting is
function lambda at 0x0671C198
First of drop all the the unnecessary imports and stick to what you really need. Symbolic math is what sympy was made for so check out the documentation for that.
In sympy you have to define symbols first
import sympy
x = symbols('x')
Now you would use the symbol x to construct an expression using builtin operators and functions in the sympy module. Be aware that ** is exponentiation and ^ is logical xor.
f = x ** 2 * sympy.exp(-x)
dfdx = sympy.diff(f, x)
d2fdx2 = sympy.diff(f, x, x)
g = sympy.exp(x) / sympy.factorial(2) * d2fdx2
When you write g in the interactive interpreter it will write the expression the way you want it. Can't show that here but atleast I can do this:
>>> print(g)
x**2/2 - 2*x + 1
You cannot do what you want with the math, sympy.mpmath and numpy modules as they exist for numerical evalutions - they want numbers and give you number.
If you later want to evaluate your expression for a given value of x you could do
val_at_point = g.evalf(subs={x: 1.5})
where subs is a dictionary.
Or you could turn g into a python lambda function:
fun_g = sympy.lambdify(x, g)
val_at_point = fun_g(1.5)
If you're doing this for a math class you probably want to be working in the interpreter anyway in which case you can start by writing
>>> from sympy import *
so that you can skip all the sympy. stuff in the above code samples. I left them there just to show where symbols come from.