x = Symbol('x')
f = x**2-3
def return_y_intercept(f):
return [the y-intercepts]
How is it possible using something like the structure above write a function that returns the y-intercepts of it's argument?
The y-intercept just means that you substitute 0 for x, so just do f.subs(x, 0).
Try using sympy.coeff, here, so like this:
Y-intercept as Coordinates
from sympy import Symbol
x = Symbol('x')
f = x**2-3
def return_y_intercept(f):
return [0,f.coeff(x,0)] #return coordintes of y-intercept
print return_y_intercept(f)
Output:
0,-3
Y-intercept:
from sympy import Symbol
x = Symbol('x')
f = x**2-3
def return_y_intercept(f):
return [f.coeff(x,0)] #return just the y-intercept
print return_y_intercept(f)
Output:
-3
try it on the online sympy interpreter here
Related
import matplotlib.pyplot as plt
string = input("Please enter a function: ")
Here the code that I want to convert. I want to convert this to variable to graph the function. Other part of the code will be:
domain = [x for x in range(-10,10)]
range = [string for x in domain]
And I want the string in range be variable in order to Python can run the code. For example if a user enter, let's say,
string = "x ** 2 + x * 2 + 1"
Then I want a method or something that will convert this string to a variable. And in the end I want to get:
string = x ** 2 + x * 2 + 1
By getting this I can get a plot from matplotlib. Finally code will be:
domain = [x for x in range(-10,10)]
range = [x ** 2 + x * 2 + 1 for x in domain]
Thanks in advance!
A quick & dirty approach would be to use the native function eval. For instance define the following high-order function:
def str_to_func(string):
return lambda x: eval(string)
which can be used in this way:
function = str_to_func(string)
values = [function(x) for x in domain]
plt.plot(domain, values)
I am working with SymPy vectors:
from sympy import *
from sympy.vector import *
N = CoordSys3D('N')
x = symbols('x')
v = x * N.i + x**2 * N.j
vf=factor(v)
vf1=vf.as_independent(Vector)[1]
type(vf1)
# sympy.core.add.Add
I need to calculate dot(vf1,vf1). But SymPy does not evaluate the dot product:
ss = dot(vf1,vf1)
ss
# 1 + 2*Dot(N.i, N.j*x) + Dot(N.j*x, N.j*x)
I suspect, this is because vf1 has been metamorphosed into another type, i.e. sympy.core.add.Add).
Is there a way to make SymPy evaluate ss? Is there a way to cast vf1 as a sympy.vector...?
EDIT
I have written a function that does the dot product. But I need to do this the SymPy way, so I don't have to re-implement my own version of every function in sympy.vector.
Yes, the as_independent does not respect the class of Add or Mul that it is dealing with and only uses Mul/Add (instead of VectorMul/VectorAdd in your case). This can be fixed with a transform:
>>> from sympy.core.rules import Transform
>>> T = Transform(lambda x: (VectorMul if x.is_Mul else VectorAdd)(*x.args),
... lambda x: x.is_Add or x.is_Mul and any(isinstance(i,BaseVector)
... for i in x.args))
>>> vf1.xreplace(T)
N.i + x*N.j
>>> dot(_,_)
x**2 + 1
I have a very complicated non-linear function f. I want to get taylor series till degree n in a form of sympy expression for the function f at value x.
f is a regular python function not a sympy expression. Output of get_polynomial should be a sympy expression.
Is there any function that will get taylor-series of a function?
from math import sin, cos, log, e
def f(x):
# a very complicated function
y = sin(x) + cos(x) + log(abs(x)+2)**2/e**2 + sin(cos(x/2)**2) + 1
return y
def get_polynomial(function, x, degree):
# .......
# using Taylor Series
# .......
return sympy_expression_for_function_at_value_x
Output:
get_polynomial(sin, 0, 3) ---> 0 + x + 0*x**2 + (1/6)*x**3
get_polynomial(lambda x: e**x, 0, 1) --> 1 + x
In a similar manner I wanna calculate get_polynomial(f, 0, 3)
The following code is close to what you're looking for. What this does it to parse the code the of the function you wish you expand into a Taylor series, convert it into a symbolic representation using Sympy and then compute the Taylor expansion.
One limitation is that you need to have an explicit function definition so you can't use lambda expressions. This can be solved with further work. Otherwise the code does what you ask for. Note that when you define a function, it has to contain a line of the form y = ... for this code to work
from inspect import *
import sympy
def f(x):
# a very complicated function
y = sin(x) + cos(x) + log(abs(x)+2)**2/e**2 + sin(cos(x/2)**2) + 1
return y
def my_sin(x):
y = sin(x)
return y
def my_exp(x):
y = e**x
return y
x = sympy.Symbol('x')
def get_polynomial(function, x0, degree):
# parse function definition code
lines_list = getsource(function).split("\n")
for line in lines_list:
if '=' in line:
func_def = line
elements = func_def.split('=')
line = ' '.join(elements[1:])
sympy_function = sympy.sympify(line)
# compute taylor expansion symbolically
i = 0
taylor_exp = sympy.Integer(0)
while i <= degree:
taylor_exp = taylor_exp + (sympy.diff(sympy_function,x,i).subs(x,x0))/(sympy.factorial(i))*(x-x0)**i
i += 1
return taylor_exp
print (get_polynomial(my_sin,0,5))
print (get_polynomial(my_exp,0,5))
print (get_polynomial(f,0,5))
I want to define the arbitrary function f. I know that f always returns a positive number. I want sympy to be able to use this knowledge when running simplifications (especially the three power rules mentioned in the simplify documentation). Is there a way to do this? I'm looking for something like the below:
f = Function("f", positive = True)
g = Function("g", positive = True)
x = symbols("x")
y = symbols("y")
n = symbols("n", real = True)
test = ( f(x) * g(y) ) ** n
# This should work but doesn't
expand_power_base(test)
Functions defined like Function('f') do not support assumptions at this time. You'll need to create a subclass explicitly, like
class f(Function):
is_positive = True
Here is a not-so-great way of going about things:
alphabet = list(string.ascii_lowercase)
def assert_positive(value, args):
result = value
for i in range( len(args) ):
a_symbol = symbols( alphabet[i], positive = True)
result = result.subs(args[i], a_symbol)
result = simplify(result)
for i in range( len(args) ):
a_symbol = symbols( alphabet[i], positive = True)
result = result.subs(a_symbol, args[i])
return(result)
One workaround is to call expand_power_base with the force=True option. This forces sympy to perform power simplifications, irrespective of assumptions.
import sympy as sp
f = sp.Function("f")
g = sp.Function("g")
x, y, n = sp.symbols("x, y, n")
test = ( f(x) * g(y) ) ** n
sp.expand_power_base(test, force=True)
f(x)**n*g(y)**n
I am trying to find the maximum of function when I give it a range of values and then put that same value into an array for later use. In this case I have 2 parameters, one being the x and the other the theta. My issue is that it isn't looping around to the next x value in the list. Is there a way to make it loop around and and set the maximum into an array?
import sympy.mpmath as mp
import numpy as np
import scipy.optimize as sc
from scipy.optimize import fmin
import matplotlib.pyplot as plt
#INPUT
c = 299792458. #speed of light
f = 300e6 #frequency
lmda = c/f #lambda
C = 0.5772 #Euler's constant
def E(x):
i = [] #creates an empty list
for z in x:
def kl(x):
return (2*np.pi/lmda)*x*lmda/2
def U(theta):
u = (np.cos(kl(z)*np.cos(theta))-np.cos(kl(z)))/np.sin(theta)
return u
theta = np.linspace(0.0001,np.pi,1000)
E_max = fmin(lambda theta: -U(theta), 0)
i+=[E_max]
return np.array(i)
def Denom(x):
y = [] #creates an array
for z in x:
def kl(x):
return (2*np.pi/lmda)*x*lmda
def Integrand(x):
f =np.abs( mp.ci(kl(x)) + 0.5*np.sin(kl(x))*(mp.si(2*kl(x))-2*mp.si(kl(x))) + 0.5*np.cos(kl(x))*(2*mp.ci(kl(x)) - mp.ci(2*kl(x))))
return f
PWR_tot = Integrand(z)
y+=[PWR_tot]
return np.array(y)
x = np.linspace(0.0001,5.,1000)
Directivity = E(x)/Demon(x)
plt.plot(x,Directivity)
plt.ylim(ymin = 0)
plt.show()
The structure of your code is not correct, that is why you don't get any result. First, you define functions within for loops. This does not yield an error, but what you actually want to do is define the function earlier and then call it in the for loop, as such:
def myfunction(x):
return x+ 3
for y in range(0,4):
print( myfunction(y) )
Also notice that the return statement has to be indented in order to belong to the function, as joel goldstick pointed out. Otherwise, the function will return nothing. The same holds for every statement in your E(x) function.
This is the elaboration you asked for above:
Your code:
def E(x):
i = [] #creates an empty list
for z in x:
def kl(x):
return (2*np.pi/lmda)*x*lmda/2
def U(theta):
u = (np.cos(kl(z)*np.cos(theta))-np.cos(kl(z)))/np.sin(theta)
return u
theta = np.linspace(0.0001,np.pi,1000)
E_max = fmin(lambda theta: -U(theta), 0)
i+=[E_max]
return np.array(i)
Your code with some edits to fix indentation issues:
def kl(x):
return (2*np.pi/lmda)*x*lmda/2
def U(theta):
u = (np.cos(kl(z)*np.cos(theta))-np.cos(kl(z)))/np.sin(theta)
return u
def E(x):
i = [] #creates an empty list
for z in x:
theta = np.linspace(0.0001,np.pi,1000)
E_max = fmin(lambda theta: -U(theta), 0)
i+=[E_max] # this line looks weird is E_max an list?
#perhaps:
i.append(E_max)
return np.array(i)
That is just the top part of your code. The bottom part needs similar treatment. Also sprinkle in some print statements in your loops to see if they are doing what you think they should