I am busy just doing some code on the bisection method. It is easy of course to just write the script and run it. However, the trick comes in when I want to define a function that will take an expression such as x**2 as an input. I've scrapped something together though. It sort of gets the job done but then at my first if statement it complains about not being able to multiply a function by a function. How would I solve this problem as well?
I really tried doing my homework on this problem before asking and unfortunately cannot find the solution. I would just love to know how to do this though.
from sympy.abc import x
def bisect(f, a, b):
f = lambda x: f
f_a, f_b = f(a), f(b)
tol = 1e-4
count = 0
print '\t'.join( ['Step' , 'a', 'b', 'c', 'f(c) ' , '(b-a)/2)'])
while (b-a)/float(2) > tol:
c = (a+b)/2
f_c = f(c)
print '\t'.join( [str(count) , str(a) , str(b) , str(c), str((b-a)/float(2) )])
if f_a*f_c < 0:
b = c
f_b = f_c
else:
a = c
f_a = f_c
count = count + 1
Is this what you need to know?
>>> def demo(func):
... for i in range(5):
... print func( float(i))
...
>>> demo( lambda x: x**2 + 2*x - 5 )
-5.0
-2.0
3.0
10.0
19.0
You can also pass in a function created with def as well as a one-liner defined with lambda. the above is the same as
def foo(x):
return x**2 + 2*x - 5
demo( foo)
The other thing you might want to know is that
definition = "x**2 + 2*x - 5" # or read it from the user as text input
demo( eval( "lambda x: " + definition))
works ...
obligatory warning, "eval is evil", accepting Python code from a user and executing it is generally regarded as a security no-no-NO! However, if this code is run by the same user who is experimenting with plotting mathematical forms, no great harm can come of it. He can't do anything worse than what he could do with python at the command line. If you were to do anything like this in a web-server or suchlike, I would fear for your employment and future prospects thereof!
Let's assume you have created an expression for function f using sympy:
f = x**2-0.1
Your bisect function will work if you change the lambda definition:
def bisect(fexpr, a, b):
f = lambda xval: fexpr.subs(x,xval)
f_a, f_b = f(a), f(b)
...
Related
def cost(d,c):
return [insert formula]
cost=sp.lambdify([d,c],cost(d,c))
In the context of the problem, there is a way to write c in terms of d. I called this formula for c "rs". I am trying to change cost to a function dependent on only d with the below code.
cost=sp.lambdify(d,cost(d,rs))
However, if I were to run cost(8) or whatever, I am told
"String fallback in sympify has been deprecated since SymPy 1.6. Use
sympify(str(obj)) or sympy.core.sympify.converter or obj.sympy
instead. See https://github.com/sympy/sympy/issues/18066 for more
info."
So what is the proper way to attack this problem?
Maybe something like this?
>>> def cost(a, b):
... return a + b
...
>>> def rs(a):
... return a**2
...
>>> cost_a = lambda a: cost(a, rs(a))
>>> cost_a(2) # cost(a, rs(a)) = cost(a, a**2) = a + a**2 = a*(1 + a)
6
Let's say I have this function in a python module:
def functionmaker(a,b):
return lambda x: (a*x) + b
Now let's say I am given a list of this format:
ablist = [[a1, b1], [a2, b2]...[an, bn]] of arbitrary length.
My goal is to add up all the resulting functions you get from these a's and b's.
Of course, with the simple example I gave of ax+b, you could algebraically work it out to being (a1 + a2 + ... an)x + (b1 + b2 + ... bn). But let's ignore that for a moment. The function I am actually working with is a contracted gaussian molecular orbital function, and it's not as easy to trick your way out of the problem with algebra.
What I wanted to do was something like this:
function = lambda x: (a1*x) + b1
q = 2
while q < n:
function = lambda x: function(x) + (ablist[q][0]*x) + ablist[q][1])
q += 1
But it seems you can't call a function inside itself like that. I was hoping it would just over-write the old version of "function" with the new one, but I guess not. I guess I probably need to do some kind of recursive way, but maybe there is a nicer way?
By the way I am using python 2.7.
You can do something like this:
>>> def functionmaker(a, b):
... return lambda x: a*x + b
...
>>> def summer_funcs(args):
... return lambda x: sum(functionmaker(*a)(x) for a in args)
...
>>> arguments = [(1,2), (3,4), (5,6)]
>>> summer_funcs(arguments)(1)
21
Or if you prefer:
>>> f = summer_funcs(arguments)
>>> f(1)
21
>>> f(2)
30
If I've correctly understood your question, you could use the built-in sum() function and pass it a generator expression argument to accomplish the goal:
def functionmaker(a, b):
return lambda x: (a*x) + b
ablist = [(1,2), (3,4), (5,6)]
x = 1
total = sum(functionmaker(a, b)(x) for a, b in ablist)
print(total) # -> 21
If you need to compute this quantity for many different values of x, then it might be worthwhile to optimize things for doing that:
functions = [functionmaker(a, b) for a, b in ablist]
sum_of_functions = lambda x: sum(function(x) for function in functions)
for x in (1, 1.5, 2):
print('sum_of_functions(x={:.1f}) -> {:.1f}'.format(x, sum_of_functions(x)))
Output:
sum_of_functions(x=1.0) -> 21.0
sum_of_functions(x=1.5) -> 25.5
sum_of_functions(x=2.0) -> 30.0
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)
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
I'm trying to write a lambda-expression that calls itself, but i can't seem to find any syntax for that, or even if it's possible.
Essentially what I wanted to transfer the following function into the following lambda expression: (I realize it's a silly application, it just adds, but I'm exploring what I can do with lambda-expressions in python)
def add(a, b):
if a <= 0:
return b
else:
return 1 + add(a - 1, b)
add = lambda a, b: [1 + add(a-1, b), b][a <= 0]
but calling the lambda form of add results in a runtime error because the maximum recursion depth is reached. Is it even possible to do this in python? Or am I just making some stupid mistake? Oh, I'm using python3.0, but I don't think that should matter?
Maybe you need a Y combinator?
Edit - make that a Z combinator (I hadn't realized that Y combinators are more for call-by-name)
Using the definition of the Z combinator from Wikipedia
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
Using this, you can then define add as a completely anonymous function (ie. no reference to its name in its definition)
>>> add = Z(lambda f: lambda a, b: b if a <= 0 else 1 + f(a - 1, b))
>>> add(1, 1)
2
>>> add(1, 5)
6
Perhaps you should try the Z combinator, where this example is from:
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
>>> fact = lambda f: lambda x: 1 if x == 0 else x * f(x-1)
>>> Z(fact)(5)
120
First of all recursive lambda expressions are completely unnecessary. As you yourself point out, for the lambda expression to call itself, it needs to have a name. But lambda expressions is nothing else than anonymous functions. So if you give the lambda expression a name, it's no longer a lambda expression, but a function.
Hence, using a lambda expression is useless, and will only confuse people. So create it with a def instead.
But yes, as you yourself discovered, lambda expressions can be recursive. Your own example is. It's in fact so fantastically recursive that you exceed the maximum recursion depth. So it's recursive alright. Your problem is that you always call add in the expression, so the recursion never stops. Don't do that. Your expression can be expressed like this instead:
add = lambda a, b: a > 0 and (1 + add(a-1, b)) or b
Which takes care of that problem. However, your first def is the correct way of doing it.
add = lambda a, b: b if a <= 0 else 1 + add(a - 1, b)
You want the Y combinator, or some other fixed point combinator.
Here's an example implementation as a Python lambda expression:
Y = lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg)))
Use it like so:
factorial = Y(lambda f: (lambda num: num and num * f(num - 1) or 1))
That is, you pass into Y() a single-argument function (or lambda), which receives as its argument a recursive version of itself. So the function doesn't need to know its own name, since it gets a reference to itself instead.
Note that this does get tricky for your add() function because the Y combinator only supports passing a single argument. You can get more arguments by currying -- but I'll leave that as an exercise for the reader. :-)
a little late ... but I just found this gem # http://metapython.blogspot.com/2010/11/recursive-lambda-functions.html
def myself (*args, **kw):
caller_frame = currentframe(1)
code = caller_frame.f_code
return FunctionType(code, caller_frame.f_globals)(*args,**kw)
print "5! = "
print (lambda x:1 if n <= 1 else myself(n-1)*n)(5)