I'm trying to teach myself programming and am currently working my way through 'A Primer on Scientific Programming with Python' by Hans Petter Langtangen.
Right now I'm on Exercise 3.20. Unfortunately I don't have any solutions to the problems..
I know I can use an arbitrary (mathematical) function f in the definition of a method:
def diff(f,x,h=0.001):
return (f(x+h)-f(x-h))/2*h
And when I call it i can use whatever function I wish:
print diff(math.exp,0)
print diff(math.cos,2*math.pi)
So here's my question:
Is There a way to accomodate more complex functions in this way?
Say for example I would like to approximate the derivative of a function like
x(t) = e^(-(t-4)^2)
like I did above for cos(x) and e^(x).
Edit: maybe I should be more clear. I'm not specifically trying to differentiate this one function e^(-(t-4)^2) but would like to define a method that takes ANY function of x as an argument and approximates a derivative at point x.
I was impressed when I learned that you could do it for simple functions like cos(x), sin(x) and exp(x) at all. So I thought if that works there must be a way to make it more general..
Sure, just define it first:
def x(t):
return math.exp(-(t-4)**2)
print diff(x, 0)
Instead of using def, it's often possible to use lambda if the function consists of a single expression that is returned:
print diff(lambda t: math.exp(-(t-4)**2), 0)
sure:
def x(t):
return diff(math.exp(-(t-4)**2))
Related
If you define a function in your python script and later want to use this function and possibly others inside a different function would this always work or are there any cases where this might cause issues? Also is there ever a case where this is considered bad practice?
E.g
Say I define a simple function to square a number and then use this function inside a function to some those square numbers, this seems to work however are there any cases with more complex functions where this could cause an issue (embedding functions inside functions).
def square(a):
c = a**2
return c
square(2)
def sum_of_squares(d,e):
x = square(d) + square(e) # Using the square function defined earlier
return x
sum_of_squares(2,4)
Note Not sure if this is the right forum to ask this question so feel free to move it if so.
Not only you can call functions in other functions, but the function itself inside the same function known as recursion. Check out this function of calculating a factorial as an example of recursion.
def factorial(n):
if n == 1:
return n
else:
return n * factorial(n-1)
So there isn't any case where calling a function inside other function (or same) would fail provided you are using the right syntax:)
If I have a multivariable function such as
F= lambda x,y: x**2+y**2
and if I need to use the input x0=np.array([1,1])
May I know how I should use x0 to get the value from F?
I understand that I could use something like F(x0[0],x0[1])
But I would like to know whether there is a way that I can directly use x0 rather than calling each cordinate manually
Appreciate your help
Python lets you do this by doing F(*x0), which expands the array into the parameters. In other languages this is sometimes called "splatting".
I would like to know why these two "programs" produce different output
f(x)=x^2
f(90).mod(7)
and
def f(x):
return(x^2)
f(90).mod(7)
Thanks
Great question! Let's take a deeper look at the functions in question.
f(x)=x^2
def g(x):
return(x^2)
print type(g(90))
print type(f(90))
This yields
<type 'sage.rings.integer.Integer'>
<type 'sage.symbolic.expression.Expression'>
So what you are seeing is the difference between a symbolic function defined with the f(x) notation and a Python function using the def keyword. In Sage, the former has access to a lot of stuff (e.g. calculus) that plain old Sage integers won't have.
What I would recommend in this case, just for what you need, is
sage: a = f(90)
sage: ZZ(a).mod(7)
1
or actually the possibly more robust
sage: mod(a,7)
1
Longer explanation.
For symbolic stuff, mod isn't what you think. In fact, I'm not sure it will do anything (see the documentation for mod to see how to use it for polynomial modular work over ideals, though). Here's the code (accessible with x.mod??, documentation accessible with x.mod?):
from sage.rings.ideal import is_Ideal
if not is_Ideal(I) or not I.ring() is self._parent:
I = self._parent.ideal(I)
#raise TypeError, "I = %s must be an ideal in %s"%(I, self.parent())
return I.reduce(self)
And it turns out that for generic rings (like the symbolic 'ring'), nothing happens in that last step:
return f
This is why we need to, one way or another, ask it to be an integer again. See Trac 27401.
I just wanted to ask you all about what is fitfunc, errfunc followed by scipy.optimize.leastsq is intuitively. I am not really used to python but I would like to understand this. Here is the code that I am trying to understand.
def optimize_parameters2(p0,mz):
fitfunc = lambda p,p0,mz: calculate_sp2(p, p0, mz)
errfunc = lambda p,p0,mz: exp-fitfunc(p,p0,mz)
return scipy.optimize.leastsq(errfunc, p0, args=(p0,mz))
Can someone please explain what this code is saying narratively word by word?
Sorry for being so specific but I really do have trouble understanding what it's saying.
This particular code snippet is implementing nonlinear least-squares regression to find the parameters of a curve function (this is the fitfunc, here) that best fit a set of data (exp, probably an abbreviation for "experimental data"). leastsq() is a somewhat more general routine for doing nonlinear least-squares optimization, not just curve-fitting. It requires a function (named errfunc, here) that is given a vector of parameters (p) and returns an array. It will attempt to find the parameter vector that minimizes the square of the returned array. In order to implement "fitting a curve to data" with leastsq, you have to provide an errfunc that evaluates the curve (fitfunc) at the given trial parameter vector and then subtracts it from the data (i.e. calculate the "error" or sometimes called the "residuals").
Just to be clear, none of these names are important. I'm just using them to refer to specific parts of the code snippet you provided. You will find other code that uses leastsq() for curve-fitting that names and organizes the code a little bit differently, but now that you know the general scheme, you should be able to follow along.
Python supports the creation of anonymous functions (i.e. functions that are not bound to a name) at runtime, using a construct called lambda. In your example, fitfunc and errfunc are two such lambda functions.
I believe calculate_sp2 and exp_fitfunc are simply two functions which are in the code but you didn't provide their code in the example. So, in short fitfunc actually calls the calculate_sp2 function with 3 parameters (p, p0, mz) and returns the value which is returned by calculate_sp2. errfunc also works in the same manner.
As mentioned in official documentation of scipy.optimize.leastsq, leastsq() minimizes the sum of squares of a set of equations. You can learn about the parameters of leastsq() from the official documentation.
I am giving a simple example to illustrate how lambda function works.
def add(x,y):
return x + y
def subtract(x,y):
return x-y if x > y else y-x
def main(x,y):
addition = lambda x,y: add(x,y)
subtraction = lambda x,y: subtract(x,y)
return addition(x,y) * subtraction(x,y)
print(main(7,4)) # prints 33 which is equal to (7+4)*(7-4)
I want to pass a formula within a function parameter in Python where the formula is a combination of the other function parameters. In principle this would look like this:
myfunction(x=2,y=2,z=1,formula="x+2*y/z")
6
or more generaly:
def myformula(x,y,z,formula):
return formula(x,y,z)
This would allow the user to choose any arithmetic expression in terms of x, y, and z without having to create a new function.
One of the possibility I foresee is to convert the string in line of code within the function. Anything possible like that in Python? Or any other ideas?
Thanks
Using sympy, you could evaluate mathematical expressions:
import sympy as sy
def myformula(formula, **kwargs):
expr = sy.sympify(formula)
return expr.evalf(subs=kwargs)
print(myformula(x=2,y=2,z=1,formula="x+2*y/z"))
# 6.00000000000000
print(myformula(x=2,y=2,z=1,formula="sin(x+y-z)"))
# 0.141120008059867
But note that sympy.sympify does use eval which makes it unsafe to apply to arbitrary user input
since strings can be composed to trick eval into executing arbitrary Python code.
A safer alternative is to build a parser to parse a strictly limited mathematical expressions.
Here are a few examples
Parsing expressions using ast
Using Paul McGuire's pyparsing
Your "myFormula" isn't much different than a regular lambda expression, except with the added baggage of having to parse a string into executable Python.
(lambda x,y,z: x + 2*y/z)(5, 2, 10)
As such, you could simply define myFormula as
def myFormula(*args, formula):
formula(*args)
and call it as
myFormula(5, 2, 10, lambda x, y, z: x + 2*y/z)
You could try using a lambda function. Something like this might suit you:
def myFormula(x,y,z):
return lambda x,y,z: x+2*y/z
This way you don't have to define a new function and you don't have to pass anything extra as an argument.
Extra info about lambda functions: http://www.diveintopython.net/power_of_introspection/lambda_functions.html
http://pythonconquerstheuniverse.wordpress.com/2011/08/29/lambda_tutorial/
https://docs.python.org/2/reference/expressions.html#lambda