A function f(x) which computes:
Examples
In [ ]: f(0)
Out[ ]: 1.1176470588235294
In [ ]: f(2)
Out[ ]: 0.07293440360502447
While you do not need to do the following, it is possible to
implement the function f so that it can compute the function
for array input arguments. If you do this, the examples above
should work as shown, and in addition you should be able to do:
In [ ]: import numpy
In [ ]: x = numpy.array([0, 2])
In [ ]: f(x)
Out[ ]: array([ 1.11764706, 0.0729344 ])
For the following tasks, it is not necessary to support numpy array
arguments x as shown here but you may find this useful to plot
f(x) more conveniently.
Write a function make_multiplier(factor) that returns a
function which takes an argument x and which should return
factor * x.
Examples
In [ ]: g = make_multiplier(10)
In [ ]: g(1)
Out[ ]: 10
In [ ]: g(2)
Out[ ]: 20
In [ ]: g = make_multiplier(0.5)
In [ ]: g(10)
Out[ ]: 5.0
In [ ]: g(100)
Out[ ]: 50.0
A function solve_freefall(ts, v0) which solves the following
ordinary differential equation
where m=80 kg is the mass and A=0.5 m^{2} is the surface area of an
object falling through the atmosphere, c=0.25 kg/m^{3} is
a friction coefficient, and g=9.81 m/s^{2} the
Earth's gravitational acceleration.
The argument ts is a sequence containing time steps for which we
desire the solution v(t). The first value in ts is the
initial time t0. The second argument v0 is the initial
value for the solution at time t0, i.e. v0=v(t0).
The function solve_freefall should return an array vs
containing (an approximation of) the solution for v(t) for all
elements in ts, i.e. vs=v(ts). (It is okay to return the
object that odeint returns .)
(This is analogous to the way that the function solve_ode0(ts,y0) in
the file ode0.py computes and returns
the numerical solution of the differential equation dy/dt=-2*y.)
Example:
In [ ]: solve_freefall([0, 1], 0)
Out[ ]: array([[ 0. ],
[ 9.7601827]])
In [ ]: solve_freefall([0, 1], v0=10)
Out[ ]: array([[ 10. ],
[ 19.45769962]])
You should plot the solution v(t) to check your implementation --
do you understand and can you explain how the velocity changes?
You can also compute the final (asymptotic) velocity analytically
when turbulent friction and gravitational pull are equal (in this
case dv/dt=0). Does this match the velocity that solve_freefall
returns for large times t?
Other questions to entertain yourself:
- what happens if the initial velocity is not 0?
- What if it is negative (what does it mean)?
- What happens if the initial velocity is very large?
Extend your function solve_freefall so that it takes a third
argument for the mass m with default value 80 kg.
(This is analogous to the way that the function solve_ode1 in
the file ode1.py treats the parameter c in solving
the differential equation dy/dt=-c*y.)
Example:
In [ ]: solve_freefall([0, 1], v0=0)
Out[ ]: array([[ 0. ],
[ 9.7601827]])
In [ ]: solve_freefall([0, 1], v0=0, m=80)
Out[ ]: array([[ 0. ],
[ 9.7601827]])
In [ ]: solve_freefall([0, 1], v0=0, m=200)
Out[ ]: array([[ 0. ],
[ 9.79000028]])
How does the final velocity change if you change the mass m of
the object? Is this in agreement with the analytical expression for
the final velocity that you have used in the previous question?
Write a function integrate_f_from0(b) which computes (an approximation of)
where the function f(x) is as defined in exercise 1 above. The function
integrate_f_from0(b) should return a floating point number.
Write a function find_max_f() which returns (an approximation of) the
x for which f(x) takes the maximum value. Your function
find_max_f should return a floating point number.
Write a function find_f_equals_1() which returns a float which is (an
approximation of) the x for which f(x)=1. We are only
interested in the solution where x is negative.
Write a function lin_int(xs, ys) which accepts sequences xs and ys of data as input,
and returns a callable object f(x) which returns y(x) using linear interpolation
between the points provided by the data xs and ys.
You can write your own interpolation function or use a library function for this.
Example
In [ ]: xs = [1, 2, 3]
In [ ]: ys = [10, 20, 15]
In [ ]: f = lin_int(xs, ys)
In [ ]: f(1)
Out[ ]: array(10.0)
In [ ]: f(2)
Out[ ]: array(20.0)
In [ ]: f(1.5)
Out[ ]: array(15.0)
In [ ]: f(2.5)
Out[ ]: array(17.5)
Write a function make_oscillator(frequency) that returns a
function which takes a floating point value t
to represent time, and returns sin(t * frequency).
Examples
In [ ]: osc1 = make_oscillator(1)
In [ ]: osc1(0 * math.pi)
Out[ ]: 0.0
In [ ]: osc1(0.25 * math.pi)
Out[ ]: 0.7071067811865475
In [ ]: osc1(0.5 * math.pi)
Out[ ]: 1.0
In [ ]: osc2 = make_oscillator(2)
In [ ]: osc2(0 * math.pi)
Out[ ]: 0.0
In [ ]: osc2(0.25 * math.pi)
Out[ ]: 1.0