Python: addition of function in a for loop - python

Dear python Stackoverflow users,
I want to add gaussian functions in a loop as it can be done with integer with the += sign. But I have no idea how to reasign a function value within a loop.
I have tried something like:
def gaussian(x, mu, sig):
return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))
def f(x):
return 0
for i in xdata:
f(x) = f(x) + gaussian(x,i,20)
But I obtained the message "SyntaxError: can't assign to function call"
How could I make this work?
Thanks!

As per my comment:
Replace f(x) in your code by y and replace def f(x): return 0 by y = 0.
You replied:
Ok, it works! Then a function can be defined only with a letter, without mentioning the variable!
That’s not really what’s going on. You are not defining a function. Your desired use of f(x) is not a function. The function f you defined does only one thing:
def f (x):
return 0
The function will always return 0. Once the function is defined like that, it cannot be changed (without replacing it by another function).
What you want to do is collect a function result—but not the result of f but the result of gaussian. Or actually, you want to collect all the results of the gaussian function calls and sum them up.
So what you do is create a variable which you add your results to, which as such represents the sum of those function calls.

def gaussian(x, mu, sig):
return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))
y = sum(gaussian(x, i, 20) for i in xdata)

f(x) return a result, so it is as you say 0 = 12, for example... That will throw an error, because '=' is assignment operator, so at left of it, you should only have a variable (or a constant for first assignment...).
So maybe you wanted to do:
y = f(x) + gaussian(x,i,20)
But I don't want why you want to do a "+=", because it is only for variables... And your function always returns 0. So you might just say, instead of
def f(x):
return 0
simply
y = 0
and then, tell after in the loop
y += gaussian(x, i, 20).
Or if you want to build a curve, you can use an array.
There is also an other error:
x IS NOT DEFINED in your loop (defined in two functions, but only as local vars)

Related

How to find out which values a function f is called when using scipy.integrate.quad?

I have a function f(x) = 1/x^2 and I evaluate the integral from 0 to 1 using scipy.integrate.quad. scipy.integrate.quad is an adaptive integration routine and I would like to know in which regions of [0,1] is the function f evaluated. So, for which values of x is the function f called when making an estimate of the integral?
I'm thinking of using a global variable and appending the x values called to it to keep track of the which x values get used. However, I'm not too familiar on how to do this and any help would be greatly apprecaited, thanks.
The plan is to then plot a histogram to see what regions in the interval [0,1] are evaluated the most.
You could use a decorator class that saves each value x before evaluating the function:
class MemoizePoints:
def __init__(self, fun):
self.fun = fun
self.points = []
def __call__(self, x, *args):
self.points.append(x)
return self.fun(x, *args)
#MemoizePoints
def fun(x):
return 1 / x**2
quad(fun, a = 1e-6, b = 1.0)
Then, fun.points contains all the x values for which the function f was evaluated.
Here, the decorator #MemoizePoints is just syntactic sugar for
def fun(x):
return 1 / x**2
fun = MemoizePoints(fun)

Basic Python if statements

I'm learning Python and I'm trying to understand this line if I call f(-1):
x = 0
def f(x):
if x < 0:
return g(-x)
else:
return g(x)
def g(x):
return 2*x + 3
If I call f(-1) I get 5. But I incorrectly interpret that I would get 1. This is my interpretation process:
Since x=-1 it should return g(-x). There is no def g(-x) though. However if it returns def g(x) then we should get 2*x+3, which is 1?
Don't know where I misunderstand.
Thanks
Think of g as the function and x as input to the function.
Furthermore, x is also just like any other variable name.
This means I could instead rename the x variable in the g function to anything I want.
I could also call g anything I want.
Example:
def f(x):
if x < 0:
return grumpy_function(-x)
else:
return grumpy_function(x)
def grumpy_function(cool_value):
return 2*cool_value + 3
Now try to walk through the logic using these above functions...
f(-1) causes the if statement x<0 to be true.
So we will execute the line return grumpy_function(-x)
We know that x=-1, so this means -x = -(-1) = 1.
Therefore cool_value is actually 1 not -1.
Now go to grumpy_function: 2*1+3 = 5.
when call g(-x), in your case, it equals g(-(-1)), which is g(1)
When you specify def f(x) or def g(x), you're saying that, in the following context, x is going to be the name for the actual parameter of these two methods, regardless of the x=0 defined outside.
That being said, the following lines are equivalent:
f(-1)
g(1) # because if x < 0 is True
2 * 1 + 3
5
From your code, it is not exactly clear to me which of the xes you'd like to refer to the global x=0 and which of them should refer to the function's parameter, like -1 in your example. You should make this distinction yourself and name them differently, for example, x and y. As far as I know, if you name your function parameters the same as your global variables, you lose access to the global variables from within the function body (except for globals tricks).

How can i get the errors of each iteration using fsolve to determine the root of a polynomial?

I want to have all the errors obtained from each iteration using the fsolve function to obtain the root. To be more precise, I need to plot a graph of errors as a function of the iteration.
root = fsolve(build_function,start_value,xtol = tolerance,maxfev= max_interations)
I think it's not a good practice what I will sugest, but it works.
You can define a global variable inside your "build_function" that will constantly stores the variable values for each iteration of the solver.
For example, you can try something like this:
a = []
def func(x):
global a
a.append(x)
return x**2 - 5
x0 = 1500
resp = optimize.root(func, x0)
print(a)

How to obtain a math function as an output in python

I want to do something like this
def gaussian(x, amp):
return amp * exp(-(x-cen)**2 /wid)
I want to substitute just amp and x and obtain an equation as output
for example:
gaussian(1,3)
3 * exp(-(1-cen)**2 /wid) as output.
Can I do this for a couple of lists, in one several values of amplitude an in the other their respective x's
I am not sure what you mean by "I need an equation". Do you need something you can evaluate? Then probably you can return a lambda object, and then you can evaluate that. Or you can use closure something like:
import math
def gaussian(x, amp):
def _gauss( cen,wid):
return amp * math.exp(-(x-cen)**2 /wid)
return _gauss
g = gaussian(10,1)
print g(2,4)
g now is a callable function where x and amp has been replaced so you need to pass only cen and wid
The reason why this work is because the internal function, _gauss, gets evaluated every time you call the wrapper function, doing so the function will be evaluated using the argument passed by the parent function and be used there as "static". Since then you return a function you can evaluate that and pass all the params left, this is a common technique for when a library forces you to have parameterlles callbacks.
Only draw back is more expensive then a simple function call, that is to generate the child function, not to evaluate it.
I would convert your return to a string:
def gaussian(x, amp):
return str(amp) + '* exp(-(' + str(x) + '-cen)**2 /wid)'
This should return the value you want:
gaussian(1,3)
returns
'3 * exp(-(1-cen)**2 /wid)'

Why is it considered 'powerful' to pass a function as a parameter?

I am reading through A Concise Introduction to Programming in Python by Mark J.Johnson and I stumbled upon a piece of code that uses darts to estimate the area under the graph. The code is working perfectly fine but I am getting confused as to why you would pass a function as a parameter if you could just call the function anyway.
from random import uniform
from math import exp
def area(function , a ,b ,m ,n = 1000 ): #changed parameter for better understanding
hits = 0
total_area = m * (b-a)
for i in range(n):
x = uniform(a,b)
y = uniform(0,m)
if y <= function(x):
hits += 1
frac = hits / float(n)
return frac * total_area
def f(x):
return exp(-x**2)
def g(x): #new function
return exp(-x**2) + 2
def main():
print area(f,0,2,1)
print area(g,0,2,1)
main()
He states that passing a function as a parameter is 'powerful' but I can't see why?
f is but one graph function. It is not the only function that you could define to create a graph.
You can also define other functions:
def g(x):
return 2 * x ** 2 + x + 5
and pass this into area() without having to alter that function. area() is generic enough to calculate the area of different graph functions, and all you need to do is pass in the graph function to have it calculate that area.
Had you hardcoded f instead of using a parameter, you could no longer do that.
I think the answer should be obvious, especially in this case: You can write a generic function for something like calculus integration that works on any function you pass in. You can modify the function you're integrating by supplying a new function. Likewise for other operations like graphing.

Categories

Resources