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