0

So I have to write a python script for finding the root of a function using Newton's Method, and my code isn't computing a float when evaluating the derivative at a point, it's only evaluating the sin(x) part, leaving e^x and log(2) as they are. I'm stuck, please help. This is my code so far:

from sympy import *

x=symbols('x')

f="(e**x)+(2**(-x))+2*cos(x) - 6"
func=sympify(f)
fdiff=Derivative(func, x) #this returns an expression for the derivative
val=fdiff.doit().subs({x: 0.4})
print(val) #this should output 0.187681....  instead it returns another expression

PS: evalf doesn't work either, neither does subs(x, 0.4)

  • What does val print? Can you print fdiff? – M. Chak Oct 09 '21 at 15:27
  • Did you print func ? – Ptit Xav Oct 09 '21 at 16:06
  • func prints exactly what I expect it to: e**x + 2*cos(x) - 6 + 2**(-x) – Moatasim Hisham Oct 09 '21 at 16:11
  • the `e` in your expressions is a free symbol, not the `E` (2.7...) – hpaulj Oct 09 '21 at 16:13
  • fdiff prints= Derivative(e**x + 2*cos(x) - 6 + 2**(-x), x) – Moatasim Hisham Oct 09 '21 at 16:13
  • if I use the sympy diff() function to create an expression for the derivative, for eg, fdiff=diff(func, x), then fdiff prints the expected derivative expression, i.e, e**x*log(e) - 2*sin(x) - 2**(-x)*log(2) – Moatasim Hisham Oct 09 '21 at 16:17
  • when I print val, it just subs in 0.4 for the x in e^x, computes the part with sin, and leaves log2 as it is: e**0.3*log(e) - 0.591040413322679 - 0.812252396356236*log(2) – Moatasim Hisham Oct 09 '21 at 16:19
  • @hpaulj if e was a free expression, wouldn't it produce a traceback call during the diff() assignment? since I haven't defined e as a symbol (for eg like I did with x)(also bec if I dont define x as a symbol, or if I introduce another variable y without declaring it a symbol, it throws an error)?? Are you saying that if instead of e, i used capital E, sympy would then compute the value of E^x and return it as a float? – Moatasim Hisham Oct 09 '21 at 16:22
  • `sympify` creates free symbols even if you have not defined them beforehand. But accessing them is a bit trickier since they aren't linked to a Python name. – hpaulj Oct 09 '21 at 16:23
  • update: @hpaulj was right and subbing in E for e does indeed result in the computation of e^x, but log(2) is still not being computed. – Moatasim Hisham Oct 09 '21 at 16:25
  • @hpaulj yes, took your advice and used E :), – Moatasim Hisham Oct 09 '21 at 16:25
  • Still having issues computing log(2) tho?? Got any more tips @hpaulj ? – Moatasim Hisham Oct 09 '21 at 16:26

1 Answers1

2

Using E instead of e:

In [19]: x=symbols('x')
    ...: 
    ...: f="(E**x)+(2**(-x))+2*cos(x) - 6"
    ...: func=sympify(f)
In [20]: func
Out[20]: 
 x                   -x
ℯ  + 2⋅cos(x) - 6 + 2  

Note the different script for e.

In [21]: fdiff=Derivative(func, x)
In [22]: fdiff
Out[22]: 
d ⎛ x                   -x⎞
──⎝ℯ  + 2⋅cos(x) - 6 + 2  ⎠
dx                         
In [23]: fdiff.doit()
Out[23]: 
 x               -x       
ℯ  - 2⋅sin(x) - 2  ⋅log(2)
In [24]: fdiff.doit().subs({x:.4})
Out[24]: 0.712988013023969 - 0.757858283255199⋅log(2)
In [25]: N(fdiff.doit().subs({x:.4}))
Out[25]: 0.187680680721628

With your expression

In [14]: func
Out[14]: 
 x                   -x
e  + 2⋅cos(x) - 6 + 2  
In [15]: func.free_symbols
Out[15]: {e, x}

To use this, you have to include both e and x in the subs.

In [38]: e=list(Out[15])[0]    
hpaulj
  • 221,503
  • 14
  • 230
  • 353