Passing functions in python edited - python

from math import cos
def diff1(f, x): #approximates first derivative#
h = 10**(-10)
return (f(x+h) - f(x))/h
def newtonFunction(f,x):
return x - f(x)/float(diff1(f,x))
y = cos
x0 = 3
epsilon = .001
print diff1(newtonFunction(y,x0), x0)
This is just a portion of the code, but I want to calculate diff1(f,x) where f is newtonFunction but uses the argument f passed to NewtonMinimum. diff1 already takes f and x as an argument and I get an error saying it expects two arguments for newtonFunction.

I think what you're looking for is functools.partial.

The problem is that f is not newtonFunction, rather it's the value returned by newtonFunction(y,x0). In this example that's a floating point number, hence the 'float' object not callable.
If you want to pass a function as a parameter to another function, you need to use just its name:
diff1(newtonFunction, x0)
Note also that you will then have another problem: in diff1 you're calling f with only one parameter, but newtonFunction takes two parameters.

In diff1, you are missing a * in f(x+h) and f(x) and in newtonFunction. You are also leaving y as a built-in function, so I assumed you wanted the cos of x0. Here is your edited code:
from math import cos
def diff1(f, x): #approximates first derivative#
h = 10**(-10)
return (f*(x+h) - f*(x))/h
def newtonFunction(f,x):
return x - f*(x)/float(diff1(f,x))
y = cos
x0 = 3
epsilon = .001
print diff1(newtonFunction(y(x0),x0), x0)

Related

print depending how many arguments given

Python beginner here trying to learn by doing, here i have two functions 'main','area'.
the one which has two arguments should print y = math.pi *a*b and the one which does not have two arguments should print x = math.pi *a**2 in my code it is currently printing like this " First (153.93804002589985, 0.0)
Second (78.53981633974483, 62.83185307179586) " (why its printing these 0.0 and 78.53981633974483?), how to make it check that if one parameter is given do this and if two do that ?
import math
def area(a,b=0):
y = math.pi *a*b
x = math.pi *a**2
return x,y
def main():
print("First", area(7))
print("Second", area(5, 4))
main()
If I understand you correctly, you want something like this:
import math
def area(a, b=None):
if b is None:
# b not specified:
x = math.pi * a**2
else:
# b specified:
x = math.pi * a*b
return x
def main():
print("First", area(7))
print("Second", area(5, 4))
main()
Output is
First 153.93804002589985
Second 62.83185307179586
When b is not specified, it is set to None. Then you test for that in the function.
The reason it prints e.g. (153.93804002589985, 0.0) in your original example is that you return a tuple (x, y) from the function with return x,y.
Your function returns a tuple, but the caller of the functions does not know which value to use. Instead, your function should just return either one or the other value, depending on the provided inputs. Also, I would suggest using None as the default for b since 0 might be a valid value.
def area(a, b=None):
if b is None:
return math.pi * a**2
else:
return math.pi * a * b
Alternatively, you could also use a ternary ... if ... else ... for either the entire expression or just the part that is different:
def area(a, b=None):
return math.pi * a * (b if b is not None else a)
The output will then be just
First 153.93804002589985
Second 62.83185307179586

Python fsolve tempering with object

I wrote a script in Python that finds the zero of a fairly complicated function using fsolve. The way it works is as follows. There is a class that simply stores the parameter of the function. The class has an evaluate method that returns a value based on the stored parameter and another method (inversion) that finds the parameter at which the function takes the supplied output.
The inversion method updates the parameter of the function at each iteration and it keeps on doing so until the mismatch between the value returned by the evaluate method and the supplied value is zero.
The issue that I am having is that while the value returned by the inversion method is correct, the parameter, that is part of the object, is always 0 after the inversion method terminates. Oddly enough, this issue disappears if I use root instead of fsolve. As far as I know, fsolve is just a wrapper for root with some settings on the solver algorithm and some other things enforced.
Is this a known problem with fsolve or am I doing something dumb here? The script below demonstrates the issue I am having on the sine function.
from scipy.optimize import fsolve, root
from math import sin, pi
class invertSin(object):
def __init__(self,x):
self.x = x
def evaluate(self):
return sin(self.x)
def arcsin_fsolve(self,y):
def errorfunc(xnew):
self.x = xnew
return self.evaluate() - y
soln = fsolve(errorfunc, 0.1)
return soln
def arcsin_root(self,y):
def errorfunc(xnew):
self.x = xnew
return self.evaluate() - y
soln = root(errorfunc, 0.1, method = 'anderson')
return soln
myobject = invertSin(pi/2)
x0 = myobject.arcsin_fsolve(0.5) #find x s.t. sin(x) = 0.5 using fsolve
print(x0) #this prints pi/6
x0obj = myobject.x
print(x0obj) #this always prints 0 no matter which function I invert
myobject2 = invertSin(pi/2)
x1 = myobject2.arcsin_root(0.5) #find x s.t. sin(x) = 0.5 using root
print(x1) #this prints pi/6
x1obj = myobject2.x
print(x1obj) #this prints pi/6
If you add print statements for xnew in the errorfunc then you will see that fsolve works with a list (of one element). This means that the function is re-interpreted that way, not the original function. Somehow the type information is lost after exiting the solver so that then the address/reference to that list is interpreted as floating point data, which gives the wrong value.
Setting self.x = xnew[0] there restores the desired behavior.

How to pass parameters to objective function when using minimize_scalar?

As explained here, to use scipy.optimize.minimize_scalar we need to define the objective function such as:
def f(x):
return (x - 2) * x * (x + 2)**2
Then, we will optimize it by:
from scipy.optimize import minimize_scalar
res = minimize_scalar(f)
Now, I want to define my function with a variable to optimize and several parameters. For example, some thing like:
def f(x, a, b):
return (x - a) * x * (x + a)**a + b
res = minimize_scalar(f(x, 2, 3))
How can I define the function and use it like that?
Please note that because a and b can be different each time, I cannot define them within the function definition.
Use the args argument:
args : tuple, optional
Extra arguments passed to the objective function.
The correct syntax looks like this:
res = minimize_scalar(f, args=(2, 3))

Python find root for non-zero level

Say I have the following code
def myfunc(x):
return monsterMathExpressionOf(x)
and I would like to find numerically the solution of myfunc(x) == y for diverse values of y. If y == 0 then there are a lot of root finding procedures available, e.g. from scipy. However, if I'd like to find the solution for e.g. y==1 it seems I have to define a new function
def myfunc1(x):
return myfunc(x) - 1
and then find it's root using available procedures. This way does not work for me as I will need to find a lot of solution by running a loop, and I don't want to redefine the function in each step of the loop. Is there a neater solution?
You don't have to redefine a function for every value of y: just define a single function of y that returns a function of x, and use that function inside your loop:
def wrapper(y):
def myfunc(x):
return monsterMathExpressionOf(x) - y
return myfunc
for y in y_values:
f = wrapper(y)
find_root(f, starting_point, ...)
You can also use functools.partial, which may be more to your liking:
def f(x, y):
return monsterMathExpressionOf(x) - y
for y in y_values:
g = partial(f, y=y)
find_root(g, starting_point, ...)
Read the documentation to see how partial is roughly implemented behind the scenes; you'll see it may not be too different compared to the first wrapper implementation.
#Evert's answer shows how you can do this by using either a closure or by using functools.partial, which are both fine solutions.
Another alternative is provided by many numerical solvers. Consider, for example, scipy.optimize.fsolve. That function provides the args argument, which allows you to pass additional fixed arguments to the function to be solved.
For example, suppose myfunc is x**3 + x
def myfunc(x):
return x**3 + x
Define one additional function that includes the parameter y as an argument:
def myfunc2(x, y):
return myfunc(x) - y
To solve, say, myfunc(x) = 3, you can do this:
from scipy.optimize import fsolve
x0 = 1.0 # Initial guess
sol = fsolve(myfunc2, x0, args=(3,))
Instead of defining myfunc2, you could use an anonymous function as the first argument of fsolve:
sol = fsolve(lambda x, y: myfunc(x) - y, x0, args=(3,))
But then you could accomplish the same thing using
sol = fsolve(lambda x: myfunc(x) - 3, x0)

Python: How to create a function? e.g. f(x) = ax^2

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

Categories