Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

CubicSpline/1002/NaCurves.py

From ZeroWiki
Revision as of 05:23, 7 February 2021 by imported>Unknown
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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