In [25]:
%matplotlib inline
In [26]:
import numpy as np
import matplotlib.pyplot as pl
Applications:
Interesting:
In [27]:
from IPython.display import Image
In [28]:
Image(url='http://wordlesstech.com/wp-content/uploads/2011/11/New-Map-of-the-Moon-2.jpg')
Out[28]:
In [29]:
def forwardDifference(f, x, h):
"""
A first order differentiation technique.
Parameters
----------
f : function to be differentiated
x : point of interest
h : step-size to use in approximation
"""
return (f(x + h) - f(x)) / h # From our notes
In [30]:
def centralDifference(f, x, h):
"""
A second order differentiation technique.
Also known as `symmetric difference quotient.
Parameters
----------
f : function to be differentiated
x : point of interest
h : step-size to use in approximation
"""
return (f(x + h) - f(x - h)) / (2.0 * h) # From our notes
In [31]:
np.linspace(1,10,100).shape
Out[31]:
In [33]:
def derivative(formula, func, xLower, xUpper, n):
"""
Differentiate func(x) at all points from xLower
to xUpper with n *equally spaced* points.
The differentiation formula is given by
formula(func, x, h).
"""
h = (xUpper - xLower) / float(n) # Calculate the derivative step size
xArray = np.linspace(xLower, xUpper, n) # Create an array of x values
derivArray = np.zeros(n) # Create an empty array for the derivative values
for index in range(1, n - 1): # xrange(start, stop, [step])
derivArray[index] = formula(func, xArray[index], h) # Calculate the derivative for the current
# x value using the formula passed in
return (xArray[1:-1], derivArray[1:-1]) # This returns TWO things:
# x values and the derivative values
In [32]:
def derivative2(formula, func, xLower, xUpper, n):
"""
Differentiate func(x) at all points from xLower
to xUpper with n+1 *equally spaced* points.
The differentiation formula is given by
formula(func, x, h).
"""
h = (xUpper - xLower) / float(n) # Calculate the derivative step size
xArray = np.linspace(xLower, xUpper, n) # Create an array of x values
derivArray = np.zeros(n) # Create an empty array for the derivative values
for index in range(0, n): # xrange(start, stop, [step])
derivArray[index] = formula(func, xArray[index], h) # Calculate the derivative for the current
# x value using the formula passed in
return (xArray, derivArray) # This returns TWO things:
# x values and the derivative values
We know the answer:
$$\frac{d}{dx} \left[\sin(x)\right] = \cos(x)$$
In [39]:
tau = 2*np.pi
x = np.linspace(0, tau, 100)
# Plot sin and cos
pl.plot(x, np.sin(x), color='k');
pl.plot(x, np.cos(x), color='b');
# Compute derivative using central difference formula
xder, yder = derivative2(centralDifference, np.sin, 0, tau, 10)
# Plot numerical derivative as scatter plot
pl.scatter(xder, yder, color='g', s=100, marker='+', lw=2);
# s controls marker size (experiment with it)
# lw = "linewidth" in pixels
Out[39]:
In [41]:
# Plot sin and cos
pl.plot(x, np.sin(x), color='k')
pl.plot(x, np.cos(x), color='b')
# Compute derivative using central difference formula
xder, yder = derivative2(centralDifference, np.sin, 0, tau, 100)
# Plot numerical derivative as scatter plot
pl.scatter(xder, yder, color='g', s=100, marker='*', lw=2)
Out[41]:
Gaussian Equation:
$$f(x)=A * e^{-\frac{(x-\mu)^2}{2*\sigma}}$$
In [42]:
numCraters = 5 # number of craters
widthMax = 1.0 # maximal width of Gaussian crater
heightMin = -1.0 # maximal depth of craters / valleys
heightMax = 2.0 # maximal height of hills / mountains
# 1-D Gaussian
def gaussian(x, A, mu, sigma):
return A * np.exp(-(x - mu)**2 / 2.0 / sigma**2)
# 1-D Gaussian (same thing using lambda)
#gaussian = lambda x, A, mu, sigma: A * np.exp(-(x - mu)**2 / 2. / sigma**2)
# Create an array of linearly spaced x values
xArray = np.linspace(0, 10, 500) # km
# Create an array of initially flat landscape (aka filled with 0's)
yArray = np.zeros_like(xArray)
# Add craters / mountains to landscape
for _ in range(numCraters): # '_' is the so called dummy variable
# Amplitude between heightMin and heightMax
A = np.random.rand() * (heightMax - heightMin) + heightMin
# Center location of the crater
center = np.random.rand() * xArray.max()
# Width of the crater
sigma = np.random.rand() * widthMax
# Add crater to landscape!
yArray += gaussian(xArray, A=A, mu=center, sigma=sigma)
In [43]:
pl.plot(xArray, yArray, color='k')
pl.xlabel('position [km]')
pl.ylabel('altitutde [km]')
Out[43]:
In [44]:
dydx = np.diff(yArray) / np.diff(xArray)
In [46]:
arr = np.array([1,4,10, 12,5, 7])
In [47]:
np.diff(arr)
Out[47]:
In [48]:
pl.plot(xArray[0:-1], dydx, color='r', label='slope')
pl.plot(xArray, yArray, color='k', label='data')
pl.xlabel('position [km]')
pl.ylabel('slope')
pl.plot([xArray.min(), xArray.max()], [0,0], color='k', ls=':')
#pl.ylim(-4, 4)
pl.legend(loc='best')
Out[48]:
In [49]:
slopeTolerance = 0.5
In [50]:
myArray = np.array([0, 1, 2, 3, 4]) # Create an array
tfArray = np.logical_and(myArray < 2, myArray != 0) # Use boolean logic on array
print (myArray) # Print original array
print (tfArray) # Print the True/False array (from boolean logic)
print (myArray[tfArray]) # Print the original array using True/False array to limit values
In [53]:
reachable = np.logical_and(dydx < slopeTolerance, dydx > -slopeTolerance)
unreachable = np.logical_not(reachable)
In [54]:
pl.plot(xArray, yArray, color='k')
pl.scatter(xArray[:-1][unreachable], yArray[:-1][unreachable], color='r', label='bad')
pl.scatter(xArray[:-1][reachable], yArray[:-1][reachable], color='g', label='good')
pl.legend(loc='best')
pl.xlabel('position [km]')
pl.ylabel('altitude [km]')
Out[54]:
In [ ]: