I've been trying this now for hours. I think I don't understand a basic concept, that's why I couldn't answer this question to myself so far.
What I'm trying is to implement a simple mathematical function, like this:
f(x) = x**2 + 1
After that I want to derive that function.
I've defined the symbol and function with:
x = sympy.Symbol('x')
f = sympy.Function('f')(x)
Now I'm struggling with defining the equation to this function f(x). Something like f.exp("x**2 + 1") is not working.
I also wonder how I could get a print out to the console of this function after it's finally defined.
sympy.Function is for undefined functions. Like if f = Function('f') then f(x) remains unevaluated in expressions.
If you want an actual function (like if you do f(1) it evaluates x**2 + 1 at x=1, you can use a Python function
def f(x):
return x**2 + 1
Then f(Symbol('x')) will give a symbolic x**2 + 1 and f(1) will give 2.
Or you can assign the expression to a variable
f = x**2 + 1
and use that. If you want to substitute x for a value, use subs, like
f.subs(x, 1)
Here's your solution:
>>> import sympy
>>> x = sympy.symbols('x')
>>> f = x**2 + 1
>>> sympy.diff(f, x)
2*x
Another possibility (isympy command prompt):
>>> type(x)
<class 'sympy.core.symbol.Symbol'>
>>> f = Lambda(x, x**2)
>>> f
2
x ↦ x
>>> f(3)
9
Calculating the derivative works like that:
>>> g = Lambda(x, diff(f(x), x))
>>> g
x ↦ 2x
>>> g(3)
6
Have a look to:
Sympy how to define variables for functions, integrals and polynomials
You can define it according to ways:
a python function with def as describe above
a python expression g=x**2 + 1
I recommended :
first, define a symbolic variable
x = sympy.symbols('x')
second, define a symbolic function
f = sympy.Function('f')(x)
define a formula
f = x**x+1
if you have so many variable can use this function
def symbols_builder(arg):
globals()[arg]=sp.symbols(str(arg))
if you have so many functions can use this function
def func_build(name, *args):
globals()[name]=sp.Function(str(name))(args)
Related
I would like to use sympy to help me simplify an expression, however part of what I need to carry forward are the function arguments. This is a toy problem, but something along these lines:
So far I know I can create generic functions, but propagating arguments has eluded me:
tau_1, tau_2, tau_3, x = symbols("tau_1, tau_2, tau_3, x")
f = Function("f")
g = Function("g")
h = Function("h")
delta = Function("delta")
f = tau_1 + delta(x)
g = f(x + tau_2)
This results in the following:
TypeError: 'Add' object is not callable
Is it possible to do what I'm looking for in sympy?
First, there is a difference between expressions and functions. For example, expr = sin(x) + cos(x) is an expression; it is not callable, meaning you can't do expr(y+1) or anything like that (you can do expr.subs(x, y+1), though).
If you want something that looks like sin(x) + cos(x) but is a function, use Lambda (which is SymPy's version of Python's lambda).
f = Lambda(x, sin(x) + cos(x))
Then f(y+1) is sin(y+1) + cos(y+1).
In your notation, that would be
f = Lambda(x, tau_1 + delta(x))
g = Lambda(x, f(x + tau_2))
Now g(2) is tau_1 + delta(tau_2 + 2)
Also, note that f = Function("f") is of no consequence because it's overwritten by f = ... later. You probably thought of statement f = Function("f") as a kind of type declaration: "I declare that f is a function, and expect subsequent assighments to f to know it's a function". But it's just an assignment, not a type declaration; and therefore is overwritten by any subsequent assignment. Saying f = Function("f") means you created an undefined function f, and that is it. SymPy objects are immutable, one can't add more features to f later, one can only overwrite it.
To get all variables from a sympy expression, one can call .free_symbols on the expression. I would like to retrieve all functions used in an expression. For example, from y in
from sympy import *
f = Function('f')
g = Function('g')
x = Symbol('x')
y = f(x) + 2*g(x)
I'd like to get f and g.
Any hints?
atoms does the trick:
for f in y.atoms(Function):
print(f.func)
For all functions, use atoms(Function).
In [40]: (f(x) + sin(x)).atoms(Function)
Out[40]: set([f(x), sin(x)])
For only undefined functions, use atoms(AppliedUndef).
In [41]: from sympy.core.function import AppliedUndef
In [42]: (f(x) + sin(x)).atoms(AppliedUndef)
Out[42]: set([f(x)])
I'm looking for an example of operations with logarithms in Python. I've tried with sympy and numpy and I still can't do what I want. For example, for an input like this:
log(x+1)+log(4-x)=log(100) # it's just an example
the output should give me the x value. I need to do this with any other functions like log(x+1)=4 or log(x)-log(x+1)=log(x).
Is there some method or somewhere (documentation or similar) where can I find how to do this?
I may be misunderstanding what you need to do because you said you tried sympy already. However, it looks like you just want to solve for x in an algebraic equation.
Solving for x in the equation
log(x+1)+log(4-x)=log(100)
using sympy would be
>>> from sympy import Symbol, solve, log
>>> x = Symbol('x')
>>> solve(log(x+1) + log(4-x) - log(100), x)
[3/2 - 5*sqrt(15)*I/2, 3/2 + 5*sqrt(15)*I/2]
If you want, you can check that these two solutions are correct with numpy.
>>> import numpy as np
>>> a = 3/2 - 5*np.sqrt(15)*1j/2
>>> b = 3/2 + 5*np.sqrt(15)*1j/2
>>> np.log(a + 1) + np.log(4-a)
(4.6051701859880918+0j)
>>> np.log(b + 1) + np.log(4-b)
(4.6051701859880918+0j)
>>> np.log(100)
4.6051701859880918
Is that not what you are looking for?
Since log is a non-linear function, you will need to use a non-linear solver like scipy.optimize.fsolve. It take in a function and a guess value and returns the answer in the form of an array. For simplicity reason, I defined the function as a lambda function since we don't need it outside of this line, but creating a function using standard def methods would work as well. The [0] on the back end get the value out of the array to return just the float.
import scipy.optimize
import math
scipy.optimize.fsolve(lambda x: math.log(x+1) - 4, 5)[0] # 5 is guess value
>>> 53.598
# Check
math.exp(4) - 1
>>> 53.598
Good advice already given. I just note that you can also check the answer in SymPy.
>>> L, R = log(x+1)+log(4-x), log(100)
>>> eq = Eq(L, R)
>>> eq
log(-x + 4) + log(x + 1) == log(100)
>>> sol = solve(eq)
>>> [eq.subs(x, i) for i in sol]
[True, True]
So in the Eq form the solutions were verified automatically. This is not always
true but you can use numerical evaluation to check the value:
>>> f = eq.lhs - eq.rhs; f
log(-x + 4) + log(x + 1) - log(100)
>>> f.subs(x, sol[0])
-log(100) + log(5/2 - 5*sqrt(15)*I/2) + log(5/2 + 5*sqrt(15)*I/2)
>>> _.n()
0.e-124 + 0.e-125*I
>>> f.subs(x, sol[0]).n(chop=True) # the small numbers can be chopped
0
I am trying to manipulate variables in sympy, so that after I can input them into a Python function which requires the input to be “normal” Python code. For example:
I would like to input (where x is a sympy symbol):
y = x**3 + x**2 + 3*x +5
Then, in the same code I would later like to be able to insert y into another function, lets say:
OtherFunction(y)
where y is no longer the “type” sympy symbol, but rather interpreted as if I had directly input
OtherFunction(x**3 + x**2 + 3*x +5)
Is there a way to do this?
This is already how Python works. When you define y as you show, you are creating a Python variable, y, that has the value of a SymPy expression. So if you call some function, passing y, you are actually passin the expression:
>>> y = x**3 + x**2 + 3*x +5
>>> def foo(x):
... print 'got',x
...
>>> foo(y)
got x**3 + x**2 + 3*x + 5
I want to have some sort of reference to a function but I do not know if I need to use a def f(x) or a lambda of some kind.
For instance I'd like to print f(3) and have it output 9a, or is this not how python works?
Second question: Assuming I have a working function, how do I return the degree of it?
To create a function, you define it. Functions can do anything, but their primary use pattern is taking parameters and returning values. You have to decide how exactly it transforms parameters into the return value.
For instance, if you want f(x) to return a number, then a should also be a numeric variable defined globally or inside the function:
In [1]: def f(x):
...: a = 2.5
...: return a * x**2
...:
In [2]: f(3)
Out[2]: 22.5
Or maybe you want it to return a string like this:
In [3]: def f(x):
...: return str(x**2) + 'a'
...:
In [4]: f(3)
Out[4]: '9a'
You have to specify your needs if you need more help.
EDIT: As it turns out, you want to work with polynomials or algebraic functions as objects and do some algebraic stuff with them. Python will allow doing that, but not using standard data types. You can define a class for a polynomial and then define any methods or functions to get the highest power or anything else. But Polynomial is not a built-in data type. There may be some good libraries defining such classes, though.
Python (and most other computer languages) don't do algebra, which is what you'll need if you want symbolic output like this. But you could have a function f(a,x) which returns the result for particular (numerical) values of a:
def f(a, x):
return a*x*x
But if you want a program or language which actually does algebra for you, check out sympy or commercial programs like Mathematica.
If you are just working with polynomials, and you just need a data structure which deals well with them, check out numpy and its polynomial class.
I normally use lambda for short and simple functions:
f = lambda a, x: a * x**2
here a and x are parameters of my function. You need to enter a and x
f(2,4)
If you want a as a constant parameter eg. a=2:
f = lambda x: 2 * x**2
f(5)
if you have a list of input values of x, you can combine map with lambda.
it is straighforward and easily readable.
(*map(lambda x: 3 * x**2, [1,2,3,4]),)
or
list(map(lambda x: 3 * x**2, [1,2,3,4])
cheers!
def func():
print "F(x) = 2x + 3"
x = int(raw_input('Enter an integer value for x: '))
Fx = 2 * x + 3
return Fx
print func()
have fun :)
Cheese,
you can use the def function in Python to create a math function, you could type this:
def f(x):
return(2x + (3 + 3) * 11 + 88) # <- you could make your own function.
print(f(3))
Log:
220
Like THAT
or in this:
def f(a, x):
return((a + x) ** (a * x))
then...
print(f(1, 2))
Log...
6