$\newcommand{\re}{\mathbb{R}}$
A function is something which takes some input arguments and returns one or more output values. These are called def
in Python, short for definition. They have following structure
def functionname(arg1,arg2,arg3):
DO SOME COMPUTATION
return result
The body of the function must be indented.
Whenever some piece of computation is to be repeated many times, it is best to put it inside a function. This avoids code duplication, which minimizes errors and makes it easy to maintain your code.
import numpy as np
For $x, y \in \re^n$, compute $z \in \re^n$ by
$$ z_i = x_i + y_i, \qquad 0 \le i \le n-1 $$def sum1(x,y):
z = np.empty_like(x)
for i in range(len(x)):
z[i] = x[i] + y[i]
return z
Now we can use this function.
n = 5
x = np.ones(n)
y = 2*x
z = sum1(x,y)
print(z)
print(z - (x + y))
[3. 3. 3. 3. 3.] [0. 0. 0. 0. 0.]
def sum2(x,y):
assert len(x) == len(y)
z = np.empty_like(x)
for i,(a,b) in enumerate(zip(x,y)):
z[i] = a + b
return z
First test on same inputs as before.
z = sum2(x,y)
print(z)
print(z - (x + y))
[3. 3. 3. 3. 3.] [0. 0. 0. 0. 0.]
If you try to run the following code, it will give an error.
n = 5
x = np.ones(n)
y = np.ones(n+1)
z = sum(x,y)
Given $x \in \re^n$, compute
$$ m = \min_{0 \le i \le n-1} x_i $$def minval(x):
val = x[0]
for v in x:
if v < val:
val = v
return val
Test on some random array.
x = np.random.rand(10)
mval = minval(x)
print('x = \n', x)
print('Minimum = ',mval)
print('Numpy = ', x.min())
x = [0.12886216 0.10399218 0.04901359 0.39172266 0.67803966 0.99732822 0.73175096 0.47023951 0.22952645 0.13417725] Minimum = 0.04901358860864924 Numpy = 0.04901358860864924
Given $x \in \re^n$, compute
$$ m = \min_{0 \le i \le n-1} x_i, \qquad M = \max_{0 \le i \le n-1} x_i $$def minmax(x):
min_val = x[0]
max_val = x[0]
for v in x:
if v < min_val:
min_val = v
if v > max_val:
max_val = v
return min_val, max_val
The type of returned object is tuple
.
x = np.random.rand(5)
min_val, max_val = minmax(x)
print(x)
print('Minimum =',min_val,x.min())
print('Maximum =',max_val,x.max())
[0.43746931 0.05565976 0.89235278 0.09199221 0.93404005] Minimum = 0.0556597647670255 0.0556597647670255 Maximum = 0.9340400469746285 0.9340400469746285
If the function definition is simple we can define them using lambda
$$ f(x) = \sin(2\pi x) $$f = lambda x: np.sin(2*np.pi*x)
x = np.linspace(0.0, 1.0, 100)
y = f(x)
min_val, max_val = minmax(y)
print('Minimum =',min_val)
print('Maximum =',max_val)
Minimum = -0.9998741276738751 Maximum = 0.9998741276738751
We can define lambda's with more than one argument.
g = lambda x,y: np.sin(2*np.pi*x) * np.cos(2*np.pi*y)
z = g(1.2, 2.3)
print(z)
-0.2938926261462344
def fun1(x):
a = 1
print(x + a)
def fun2(x):
a = 2
print(x + a)
def fun3(x):
print(x + a)
The variable a
inside these functions are local variables and have different values.
fun1(1)
fun2(1)
fun3(1)
2 3
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[13], line 3 1 fun1(1) 2 fun2(1) ----> 3 fun3(1) Cell In[12], line 10, in fun3(x) 9 def fun3(x): ---> 10 print(x + a) NameError: name 'a' is not defined
Variable a
is not visible in fun3
since it is a local variable in fun1
and fun2
.
p = 1.234 # Global variable, visible inside all functions.
def fun4(x):
p = 1.0 # Local variable of same name
print(x + p)
def fun5(x):
print(x + p) # Here the global variable p is used
The variable p = 1.234
which is declared outside the functions is a global variable.
fun4(1.0)
fun5(1.0)
2.0 2.234
The variable p = 1.0
is a local variable in fun4
; this is ok, you can have a local and global variable of the same name, they have independent existence. But in fun5
, the global variable p = 1.234
is used since there is no local variable of the same name. If you wanted to use the global variable, then it is fine, but if you forgot to declare p
inside fun5
, then you have a bug, and it can be difficult to detect.
You have to be very careful with global variables. If you forget to declare some variable inside a function, and a global variable with the same name exists, then your program will run but likely give wrong answers. We should ideally never use global variables, but they are rampant in jupyter notebooks. To avoid global variables, you have to declare ALL variables inside functions and not declare anything in the global scope. It is good practice not to rely on global variables, but instead write pure functions.
def sin(x):
return np.sin(x)
def cos(x):
return np.cos(x)
def run(x, f):
print(f(x))
x = np.pi/2
run(x, sin)
run(x, cos)
1.0 6.123233995736766e-17