# Cubic Spline/1002/Na Curves.py

```from wxPython.wx import *
import math
import LuDecomposition
import  TriDiagonal

DATASET = [-1.0, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0]

def givenFunction(x):
return 1 / (1 + 100 * (x**2))

class NormalFunction:
def perform(self, x):
return givenFunction(x)

class ErrorLagrange:
def __init__(self, aListX):
self.lagrange = Lagrange(aListX)
self.normalFunc = NormalFunction()

def perform(self, x):
return self.normalFunc.perform(x) - self.lagrange.perform(x)

class ErrorPiecewiseLagrange:
def __init__(self, aControlPointListX, aPieceSize):
self.piecewiseLagrange = PiecewiseLagrange(aControlPointListX, aPieceSize)
self.normalFunc = NormalFunction()

def perform(self, x):
return self.normalFunc.perform(x) - self.piecewiseLagrange.perform(x)

class ErrorSpline:
def __init__(self, aControlPointListX):
self.spline = Spline(aControlPointListX)
self.normalFunc = NormalFunction()

def perform(self, x):
return self.normalFunc.perform(x) - self.spline.perform(x)

class Lagrange:
def __init__(self, aListX):
self.controlPointListX = aListX
self.controlPointListY = self._makeControlPointListY()

def _makeControlPointListY(self):
controlPointListY = []
for x in self.controlPointListX:
controlPointListY.append(givenFunction(x))
return controlPointListY

def getControlPointListX(self):
return self.controlPointListX

def getControlPointListY(self):
return self.controlPointListY

def _basedFunction(self, x, i):
bf = 1
for j in range(0, len(self.controlPointListX)):
bf *= self._subBasedFunction(x, i, j)
return bf

def _subBasedFunction(self, x, i, j):
if i == j:
return 1
else:
return (x - self._getX(j)) / (self._getX(i) - self._getX(j))

def perform(self, x):
lg = 0.0
for i in range(0, len(self.controlPointListX)):
lg += self._basedFunction(x, i) * self._getY(i)

return lg

def _getX(self, i):
return self.controlPointListX[i]

def _getY(self, i):
return self.controlPointListY[i]

class PiecewiseLagrange:
def __init__(self, aControlPointListX, aPieceSize):
self.controlPointListX = aControlPointListX
self.pieceSize = aPieceSize

def getControlPointListX(self):
return self.controlPointListX

def perform(self, x):
if (x >= self.controlPointListX[0]) and (x < self.controlPointListX[3]):
return Lagrange(self.getPiece(1)).perform(x)
elif (x >= self.controlPointListX[3]) and (x < self.controlPointListX[6]):
return Lagrange(self.getPiece(2)).perform(x)
elif (x >= self.controlPointListX[6]) and (x < self.controlPointListX[9]):
return Lagrange(self.getPiece(3)).perform(x)
elif (x >= self.controlPointListX[9]) and (x <= self.controlPointListX[10]):
return Lagrange(self.getPiece(4)).perform(x)

def getPiece(self, i):
if ((self.pieceSize-1)*(i-1)+self.pieceSize) > self.getCountControlPoints():
return self.controlPointListX[self.getCountControlPoints()-self.pieceSize : self.getCountControlPoints()]
return self.controlPointListX[self.getFirstPiecePoint(i) : self.getEndPiecePoint(i)]

def getCountControlPoints(self):
return len(self.controlPointListX)

def getFirstPiecePoint(self, i):
return (self.pieceSize-1)*(i-1)

def getEndPiecePoint(self, i):
return (self.pieceSize-1)*(i-1)+self.pieceSize

def getCountPieces(self):
return int(math.ceil( (self.getCountControlPoints()+1) / (self.pieceSize-1) ))

class Spline:
def __init__(self, aControlPointListX):
self.controlPointListX = aControlPointListX

self.controlPointListY = self._makeControlPointListY()
self.doublePrimeListY = self._makeDoublePrimeY()

def getAi(self, i):
return (self.getDoublePrimeY(i+1) - self.getDoublePrimeY(i)) / (6 * self.deltaX(i))

def getBi(self, i):
return (self.getDoublePrimeY(i) / 2)

def getCi(self, i):
return (self.deltaY(i) / self.deltaX(i) ) - (self.deltaX(i) / 6) * (self.getDoublePrimeY(i+1) + (2*self.getDoublePrimeY(i)) )

def getDi(self, i):
return self.getYi(i)

def getXi(self, i):
return self.controlPointListX[i]

def getYi(self, i):
return self.controlPointListY[i]

def getDoublePrimeY(self, i):
return self.doublePrimeListY[i][0]

def getControlPointListX(self):
return self.controlPointListX

def getControlPointListY(self):
return self.controlPointListY

def perform(self, x):
for i in range(0, len(self.controlPointListX)-2):
if (x >= self.getXi(i)) and (x < self.getXi(i+1)):
return self._subCubicSpline(x, i)

if x >= self.getXi(len(self.controlPointListX)-2):
return self._subCubicSpline(x, len(self.controlPointListX)-2)

def _subCubicSpline(self, x, i):
return self.getAi(i) * ((x - self.getXi(i)) ** 3) + self.getBi(i) * ((x - self.getXi(i)) ** 2) + self.getCi(i) * ((x - self.getXi(i))) + self.getDi(i)

def deltaX(self, i):
return self.getXi(i+1) - self.getXi(i)

def deltaY(self, i):
return self.getYi(i+1) - self.getYi(i)

def _makeControlPointListY(self):
cplY = []
for x in self.controlPointListX:
cplY.append (givenFunction(x))
return cplY

def _makeMatrixA(self):
matrixA = self._makeEmptyMatrix()
for i in range(0,9):
matrixA[i][i] = 2 * (self.deltaX(i)+self.deltaX(i+1))
if i>0:
matrixA[i-1][i] = self.deltaX(i)
matrixA[i][i-1] = self.deltaX(i)

return matrixA

def _makeMatrixB(self):
matrixB = []
for i in range(1,10):
matrixB.append([6 * ( self.deltaY(i)/self.deltaX(i) - self.deltaY(i-1)/self.deltaX(i-1) )])

return matrixB

def _makeDoublePrimeY(self):
a = self._makeMatrixA()
b = self._makeMatrixB()

l, u = LuDecomposition.LuDecomposition(a).perform()
matrixY = TriDiagonal.getMatrixY(l, b)
tempY = TriDiagonal.getMatrixX(u, matrixY)
tempY.insert(0, [0.0])
tempY.append([0.0])

return tempY

def _makeEmptyMatrix(self):
n = 9
matrix = []
for i in range(0,n):
row = []
for j in range(0,n):
row.append(0.0)
matrix.append(row)
return matrix
```