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.
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)
x = symbols('x')
ch = 'exp(cos(cos(exp((sin(-0.06792841536110628))**(-6.045461643745118)))))'
f = lambdify(x, ch, "numpy")
print(float(f(2)))
It does not work, the programm is running and never ends(no error is issued).
My goal is to avoid this kind of cases (among multiple cases) by doing a try/except but i can't as there is no error
Why no error is released?
How can i avoid these cases ?
Thanks for your helping me !
In general, I'm not sure you can. SymPy or NumPy will keep trying to compute the number until precision is exhausted. But you can create a function that will raise and error if numbers are out of bounds for your interest:
>>> from sympy import cos as _cos, I, exp
>>> def cos(x):
... if abs(x) > 10**20: raise ValueError
... return _cos(x)
>>> exp(cos(cos(exp(5*(1+I)))))
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 2, in cos
ValueError
>>> f = lambda x: exp(cos(cos(exp(x))))
>>> f(sin(-0.06792841536110628)**-6.045461643745118)
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 1, in <lambda>
File "<string>", line 2, in cos
ValueError
But you have to think carefully about when you want to raise such an error. For example, SymPy has no trouble computing f(100) or f(100*I) if the non-error-catching cos is used. So think about when actually you want the error to rise.
lambdify is a lexical translator, converting a sympy expression to a python/numpy function.
Make a string with a symbol:
In [27]: ch = 'exp(cos(cos(exp((sin(x))**(-6.045461643745118)))))'
sympify(ch) has no problem, because it doesn't need to do any numeric calculation. So lambdify also works:
In [28]: f=lambdify(x,ch)
In [29]: f?
Signature: f(x)
Docstring:
Created with lambdify. Signature:
func(x)
Expression:
exp(cos(cos(exp((sin(x))**(-6.045461643745118)))))
Source code:
def _lambdifygenerated(x):
return (exp(cos(cos(exp(sin(x)**(-6.045461643745118))))))
The equivalent mpmath:
def _lambdifygenerated(x):
return (exp(cos(cos(exp(sin(x)**(mpf((1, 54452677612106279, -53, 56))))))))
And a working numeric evaluation:
In [33]: f(0j)
Out[33]: mpc(real='nan', imag='0.0')
Currently, I'm working on a calculator, that works similar to a 'real' calculator, when determining definite integrals.
Currently i can get it to work with functions such as
sin(x)
cos(x)
e**x
n*x**x
However, it won't accept math.sqrt(x) as a function in my code, where it simply states, that
File "C:\Users\Nikolai Lund Kühne\.spyder-py3\integration.py", line 6, in <module>
print(series(math.sqrt(x), x, x0=0, n=6))
File "C:\ProgramData\Anaconda3\lib\site-packages\sympy\core\expr.py", line 327, in __float__
raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
My code is:
from sympy.functions import sin,cos
from sympy.abc import x
from sympy import series
from pprint import pprint
# Indsæt her funktionen f(x), variablen x, udviklingspunktet x0 og antal led n
print(series(math.sqrt(x), x, x0=0, n=6))
N = int(input("Antal summer(flere summer er mere præcist): "))
a = int(input("Integrer fra: "))
b = int(input("Integrer til: "))
# Vi anvender Midpoint metoden til integration og skriver funktionen ind, som skal integreres
def integrate(N, a, b):
def f(x):
return series(math.sqrt(x), x, x0=0, n=6)
value=0
value=2
for n in range(1, N+1):
value += f(a+((n-(1/2))*((b-a)/N)))
value2 = ((b-a)/N)*value
return value2
print("...................")
print("Her er dit svar: ")
print(integrate(N, a, b))
Can anyone help me here, it's greatly appreciated.
Disclaimer: I am quite new to programming and Python and would appreciate any help given.
Sorry for the strange setup, I am used to LaTeX and MathJax when writing questions :)
You get the error:
TypeError: can't convert expression to float
Since the argument passed as expr is math.sqrt(x), and sympy doesn't expect that.
Change from math.sqrt(x) to x**0.5:
print(series(x**0.5, x, x0=0, n=6))
The same applies to line 16.
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).
import math
def p(n):
return 393000*((288200/393000)^n * math.exp(-(288200/393000)))/math.factorial(n)
print p(3)
When I run it, I get the following error message:
Traceback (most recent call last):
File "poisson.py", line 6, in <module>
print p(3)
File "poisson.py", line 4, in p
return 393000*((288200/393000)^n * math.exp(-(288200/393000)))/math.factoria
l(n)
TypeError: unsupported operand type(s) for ^: 'int' and 'float'
Replace ^ with ** in
(288200/393000)^n
Bear in mind that
288200/393000
Returns 0
Maybe you should try using decimal numbers:
import math
def p(n):
a = 393000.0 # <-- notice the .0
b = 288200.0
c = b / a
return a * ( c**n * math.exp(-c) )/ math.factorial(n)
print p(3)
Returns:
12406.890756
Is the ^ supposed to mean exponentiation? If so, use ** instead.
You can also use math.pow:
>>> import math
>>> math.pow(3,2)
9.0
Though actually it looks like maybe this isn't the best idea, since math.pow is more for C extension compatibility, and doesn't handle all the cases that ** does:
>>> 2**3000
1230231922161117176931558813276752514640713895736833715766118029160058800614672948775360067838593459582429649254051804908512884180898236823585082482065348331234959350355845017413023320111360666922624728239756880416434478315693675013413090757208690376793296658810662941824493488451726505303712916005346747908623702673480919353936813105736620402352744776903840477883651100322409301983488363802930540482487909763484098253940728685132044408863734754271212592471778643949486688511721051561970432780747454823776808464180697103083861812184348565522740195796682622205511845512080552010310050255801589349645928001133745474220715013683413907542779063759833876101354235184245096670042160720629411581502371248008430447184842098610320580417992206662247328722122088513643683907670360209162653670641130936997002170500675501374723998766005827579300723253474890612250135171889174899079911291512399773872178519018229989376L
vs.
>>> import math
>>> math.pow(2, 3000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: math range error
see http://mail.python.org/pipermail/python-list/2003-November/236169.html for a little more detail
EDIT: In response to your question as to why it returns 0.0, that's because you are raising 0 to a power - you are using / for division, which by default is integer division and will truncate. use from __future__ import division to get floating point divison.