Here mathematical notes are kept.
Contents
Abstract:
This document is about using Latex in reStructuredText and Sphinx. At the link below there is a introduction to mathematical symbols in Latex.
There are 2 ways of writing math in restructuredText:
For producing more complex math like eg an equation* environment in a LaTeX document write:
.. math::
\psi(r) = e^{-2r}
you will get:
Warning
The math markup can be used within reST files (to be parsed by Sphinx) but within your python’s docstring, the slashes need to be escaped ! :math:`\alpha` should therefore be written :math:`\\alpha` or put an “r” before the docstring
Below are some examples of Latex commands and symbols:
To do square roots like eg use :math:`\sqrt{x^2-1}`.
To do fractions like eg use :math:`\frac{1}{2}`.
In order to insert text into a formula use :math:`k_{\text{B}}T` to get like in
Use \left and \right for before brackets like in :math:`\left(\frac{1}{2}\right)^n` to get .
Displayed math can use \\ and & for line shifts and alignments, respectively.
.. math::
a & = (x + y)^2 \\
& = x^2 + 2xy + y^2
The result is:
The matrix environment can also contain \\ and &. To get like:
write:
.. math::
\left(\begin{matrix} a & b \\
c & d \end{matrix}\right)
Equations are labeled with the label option and referred to using:
:eq:`label`
E.g:
(1)
See equation (1)
is written like:
.. math::
:label: pythag
a^2 + b^2 = c^2
See equation :eq:`pythag`
Note that:
- No spaces in label name
- There should be a blank line before the actual latex code
- There should be a space between :label: and the label name
- When referred to label name should be surrounded by `
Abstract:
This chapter is about splines in Scipy and how they can be used for yield curve calculations.
It is shown that splines in scipy is probably b-splines. These splines gives different (but not nessacerily wrong) values when interpolating.
This information is important when using splines from scipy.
The natural cubic spline is already implemented in decimalpy
In order to redo the calculations below you need to install and import the package decimalpy.
>>> import decimalpy as dp
The example will be taken from [Kiusalaas] p. 119. The data are:
>>> x_data = dp.Vector([1, 2, 3, 4, 5])
>>> y_data = dp.Vector([0, 1, 0, 1, 0])
And the natural cubic spline function is instantiated by:
>>> f = dp.NaturalCubicSpline(x_data, y_data)
And the it is possible to do calculations like function values:
>>> print f(1.5), f(4.5)
0.7678571428571428571428571427 0.7678571428571428571428571427
Slopes:
>>> print f(1.5, 1), f(4.5, 1)
1.178571428571428571428571429 -1.178571428571428571428571428
and curvatures:
>>> print f(1.5, 2), f(4.5, 2)
-2.142857142857142857142857142 -2.142857142857142857142857143
and it is quite easy to do a plot:
>>> import matplotlib.pyplot as plt
>>> linspace = lambda start, stop, steps: dp.Vector([(stop - start) / (steps - 1) * i + start for i in range(steps)])
>>> xnew = linspace(1, 5, 40)
>>> x0, spread = 2, 0.5
>>> x2new = linspace(x0 - spread, x0 + spread, 40)
>>> f0x0, f1x0, f2x0 = f(x0, 0), f(x0, 1), f(x0, 2)
>>> f0Lst = dp.Vector([f(x) for x in xnew])
>>> f1Lst = dp.Vector([f0x0 + f1x0 * (x - x0) for x in x2new])
>>> f2Lst = dp.Vector([f0x0 + f1x0 * (x - x0) + f2x0 * (x - x0)**2 / 2 for x in x2new])
>>> plt.plot(x_data, y_data, 'o', xnew, f0Lst, '-', x2new, f1Lst, '-', x2new, f2Lst, '-')
>>> plt.legend(['data', 'fitted f', 'tangent', '2. order'], loc='best')
>>> plt.show()
like:
On the other hand [scipy] is well equipped with spline functionality
First set up scipy and numpy:
>>> from numpy import linspace, array, float64
>>> from scipy.interpolate import InterpolatedUnivariateSpline as spline
Use the same data as before:
>>> x_data = array([1, 2, 3, 4, 5], float64)
>>> y_data = array([0, 1, 0, 1, 0], float64)
Creating the cubic spline function:
>>> cubic = spline(x_data, y_data, k=3)
And calculate the cubic spline at 1.5 and 4.5:
>>> cubic(1.5)
array(1.1250000000000002)
>>> cubic(4.5)
array(1.1250000000000002)
This isn’t the same value as before (0.767857142857).
And if one uses interp1d from scipy.interpolate to get the function cubic2:
>>> from numpy import linspace, array, float64
>>> from scipy.interpolate import interp1d
>>> cubic2 = interp1d(x_data, y_data, kind='cubic')
Using cubic2 one gets:
>>> cubic2(1.5)
array(1.1944444444444462)
>>> cubic2(4.5)
array(1.1944444444444466)
Again a new set of values. What is a bit surprising is that a third set of values appears.
So to check the functions in a graph I do:
>>> xnew = linspace(1, 5, 40)
>>> import matplotlib.pyplot as plt
>>> plt.plot(x_data, y_data, 'o', xnew, f0Lst, '-', xnew, cubic(xnew), '--', xnew, cubic2(xnew), '+-')
>>> plt.legend(['data', 'natural spline', 'cubic', 'cubic2'], loc='best')
>>> plt.draw()
to get the graph:
And now it is obvious that scipy isn’t using the natural spline as cubic spline.
What kind of spline is used in scipy? Their code is build upon FITPACK by P. Dierckx.
The main reference is [Dierckx] which is all about b-splines. So a fair guess is that scipy also is b-splines.
This isn’t necessarily bad. Actually I haven’t looked into the differences between the 2 scipy interpolations.
Conclusion:
It matters what kind of interpolation one uses.
The difference in values is probably due to different derivations of (cubic) splines where scipy interpolation is based on b-splines.
Abstract:
This chapter is about derivation of cubic splines and the use of cubic splines for yield curve calculation.
Assume n points and n curvatures at each point.
To ease notation we introduce:
The point are known, the curvatures are assumed known
Because we want to evaluate f,f’,f’’ at it makes things easier when they are formulated as functions of and . Eg it is quite simple to see that:
So the second derivative is continous and piecewise linear.
Also the first derivative f’ can be formulated as (since :
The function which lies and for must look like (integrating twice):
where and or
This is possible if the determinant . This is the case if there isn’t 2 points with the same x-value. An asumption which already must be in place.
And since f must be continous and go through the points we have:
and
This means that the constant :
The question is what to do when there is a need for extrapolation. This is a situation quite common when talking about yieldcurve. Eg there are observed zero coupons up until year 20 but a zero coupon for year 25 is needed.
Talking about the natural cubic spline and financial cubic spline they are just linear extrapolations of the endpoints with the same slope as in the endpoints.
The only difference between the 2 cubic splines is that financial cubic spline is set to have a slope equal to zero at the endpoint to the right.
To estimate the curvatures one uses the first order derivatives:
And the assumption that the slopes are continous at the points , ie
This gives n - 2 linear equations to estimate n curvatures. This means that 2 asumptions are necessary in order to calculate the n curvtures.
Here the asumptions are . The other equations becomes :
In all n variables and n linear equations
Here the asumptions are and or:
The other equations becomes :
Also here there are in all n variables and n linear equations
Abstract:
Lagrange Interpolation has had a revelation since the Barycentric formulas were developed.
Here Barycentric Lagrange Interpolation will be examined as a tool for finding weights to approximate the first and second order derivative for a function only known by it’s functional values.
The first order is used for the duration in finance while the second order derivative is used for the convexity.
This section is highly inspired on [BerrutTrefethen], [SadiqViswanath] and [Fornberg].
Also as references [Kiusalaas] and [Ralston] has been invaluable.
First construct a polynomial with n + 1 different grid values :
This polynomial has degree n + 1. And it is obvious then that .
Consider then the tangent for p in grid value , ie.:
Now define n + 1 polynomials as:
These polynomials all satisfy:
In other words is Kroenecker’s delta. Note that the ‘s all have degree n.
Since we have:
And then when letting the grid values be the argument of l(x) (last part above is zero since is):
we have that the polynomials are well defined. This is because can be shortened out and then the polynomials are just scaled with a nonzero scaling constants.
Definition, Lagrange Interpolation and Remainder:
Consider n + 1 points . Then the unique polynomial of the minimal degree n going through all n + 1 points is:
Define as the Lagrange remainder.
Since is Kroenecker’s delta it is obvious that .
Theorem, Lagrange Remainder:
Let being an open interval containing all the n+1 grid values and f is a n+1 times continous differentiable function on :
For :
Observe that i.e. has n+1 zeros.
Also observe that since p(x) has degree n and .
Now define:
Observe that has both and x as roots, ie n+2 zeros.
According to Rolle’s theorem has n+1 zeros and successively has n zeros.
So has 1 zero, ie or
(see also)
Q.E.D.
The Lagrange Remainder can be used to limit the overall accuracy for the Lagrange Interpolation if the function f(x) is n+1 times continous differentiable on the closed interval .
This is because , ie:
So if converges to zero then the accuracy becomes of order n+1 ie .
Observation:
The Lagrange Interpolation can for a set of n+1 grid values can be seen as a way of interpolating a function value f(x) based on a weighted average of the functional values where the weights are and the accuracy will be of order .
This can be taken even further. Since only the weights depends on x the first order differentiation of can be approximated by:
So the first order derivative at x can be approximated by the functional values and the weights are and the accuracy will be of order , ie the accuracy loses 1 degree.
And successively for the second order derivative:
This makes Lagrange Interpolation well suited for finding weighted averages of functional values for derivatives of any order with high accuracy, .
Computationally Lagrange Interpolation isn’t that effective. But further analysis shows that the ‘s all have the same common factor so we have the First Barycentric formula:
(2)
where
Looking at the constant function 1 gives:
or
This way we have the Second Barycentric formula:
(3)
Both formulas shows a remarkable low dependence on the ‘s since a change in one ‘s will have a multiplicative effect only one place.
Interpolation should be done based on the Second Barycentric formula (3).
For updating the weights with an extra point consider a set of basis points to be used as a basis for Barycentric Lagrange interpolation.
When a new grid value has to be added the algorithm is:
- Calculate
- Calculate
It is obvious that there needs to be minimum 2 values. When there are only 2 grid values and then .
One of the things to use Barycentric Lagrange interpolation is to evaluate is to differentiate a curve at a point when only a set points are known with a high precision.
Usual formulas are eg, which is considered as a 3 point estimation based on the points with first coordinate (x - h, x, x + h).
The precision or accuracy is here of order 2.
Now consider:
Now according to Second Barycentric formula (3):
Letting where is one of the roots (Important assumption) we have:
The last equation will be used several times so it gets a number:
(4)
Since by design and we have for in (4):
Now for i = j we have:
This way we have:
Theorem, Barycentric first order derivative:
Consider a set of grid values and the function values . The formula for the first order derivative at one of the grid values , is:
where
Example 1:
The formula for interpolating the first order derivative can used to optimize the approximation of the derivative. Consider eg . Then and:
where i is the row index while j is the column index.
And then with:
The result is:
And this is the formula for Newton’s difference quotient.
Example 2:
Consider eg . Then and:
These coefficients are to formula 25.3.4 on page 883 in [AbramowitzStegun].
They are all of accuracy .
Looking at the middle row the formula for Newton’s difference quotient is found once again:
Differentiating (4) leads to:
(5)
Again by design and we have for in (5):
From Barycentric first order derivative Barycentric first order derivative we have so:
Finally since :
Now for i = j we have something similar as for the first order case:
This way we have:
Theorem, Barycentric second order derivative:
Consider a set of grid values and the function values . The formula for the second order derivative at one of the grid values , is:
where
Note
There is a sign error in [BerrutTrefethen] page 513
Example 2, second order:
Consider eg . Then and so:
This is usual Newton second order central finite difference approximation of accuracy , ie:
Also so:
This is usual Newton second order forward finite difference approximation of accuracy , ie:
Both results are in accordance with table 25.2 page 914 in [AbramowitzStegun].
[SadiqViswanath] study the fact that the accuracy sometimes is 1 higher than specified by Lagrange, ie the accuracy is boosted. One of their results are:
Corollary 7 page 14:
Look at the grid values . If the grid relative grid values are symmetric about 0 (in other words z is a relative grid value if and only if −z is a relative grid value) and n − m (m is the order of the derivative) is odd, the order of accuracy is boosted by 1.
So according to the corollary the Newton second order central finite difference approximation is actually of accuracy since has symmetric relative grid values and is odd. On the other hand the accuracy of the Newton second order forward finite difference approximation is still . This is confirmed by table 25.2 page 914 in [AbramowitzStegun].
Decision, the finance package:
In the finance package the derivatives numericcally will approximated such that the accuracy leading to an accuracy down to the sixteenth decimal.