def test_GenerationOf_CSHARP(self): generatedShouldBe = '''// To the best of my knowledge this code is correct. // If you find any errors or problems please contact // me directly using [email protected]. // // James using System; // Fitting target: lowest sum of squared absolute error // Fitting target value = 0.223837322455 class Polynomial_Linear { \tdouble Polynomial_Linear_model(double x_in) \t{ \t\tdouble temp; \t\ttemp = 0.0; \t\t// coefficients \t\tdouble a = -8.01913564075E+00; \t\tdouble b = 1.52644729419E+00; \t\ttemp += a + b * x_in; \t\treturn temp; \t} } ''' equation = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() generated = pyeq3.outputSourceCodeService().GetOutputSourceCodeCSHARP(equation, inDigitsOfPrecisionString = '11') self.assertEqual(generated, generatedShouldBe)
def test_GenerationOf_MATLAB(self): generatedShouldBe = '''% To the best of my knowledge this code is correct. % If you find any errors or problems please contact % me directly using [email protected]. % % James % Fitting target: lowest sum of squared absolute error % Fitting target value = 0.223837322455 function y = Polynomial_Linear_model(x_in) \ttemp = 0.0; \t% coefficients \ta = -8.01913564075E+00; \tb = 1.52644729419E+00; \ttemp = temp + a + b .* x_in; \ty = temp; ''' equation = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() generated = pyeq3.outputSourceCodeService().GetOutputSourceCodeMATLAB(equation, inDigitsOfPrecisionString = '11') self.assertEqual(generated, generatedShouldBe)
def test_GenerationOf_PYTHON(self): generatedShouldBe = '''# To the best of my knowledge this code is correct. # If you find any errors or problems please contact # me directly using [email protected]. # # James import math # Fitting target: lowest sum of squared absolute error # Fitting target value = 0.223837322455 def Polynomial_Linear_model(x_in): temp = 0.0 # coefficients a = -8.01913564075E+00 b = 1.52644729419E+00 temp += a + b * x_in return temp ''' equation = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() generated = pyeq3.outputSourceCodeService().GetOutputSourceCodePYTHON(equation, inDigitsOfPrecisionString = '11') self.assertEqual(generated, generatedShouldBe)
def test_SolveUsingSimplex_SSQREL_2D(self): coefficientsShouldBe = numpy.array([-6.74510573, 1.32459622]) model = pyeq3.Models_2D.Polynomial.Linear('SSQREL') model.estimatedCoefficients = numpy.array([1.0, 1.0]) # starting values for the simplex solver pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingSimplex(model) self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def SetParametersAndFit(equationString, inFittingTargetString, inExtendedVersionString, inTextData): # individual cluster nodes must be able to import pyeq3 import pyeq3 equation = eval'equationString +'("' + inFittingTargetString + '", "' + inExtendedVersionString + '")') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(inTextData, equation, False) try: # check for number of coefficients > number of data points to be fitted if len(equation.GetCoefficientDesignators()) > len(equation.dataCache.allDataCacheDictionary['DependentData']): return None # check for functions requiring non-zero nor non-negative data such as 1/x, etc. if equation.ShouldDataBeRejected(equation): return None equation.Solve() fittedTarget = equation.CalculateAllDataFittingTarget(equation.solvedCoefficients) if fittedTarget > 1.0E290: # error too large return None except: return None return [fittedTarget, equation.GetDisplayName(), equation.solvedCoefficients, equationString, inExtendedVersionString]
def test_GenerationOf_MATLAB(self): generatedShouldBe = '''% To the best of my knowledge this code is correct. % If you find any errors or problems please contact % me directly using [email protected]. % % James % Fitting target: lowest sum of squared absolute error % Fitting target value = 0.223837322455 function y = Polynomial_Linear_model(x_in) \ttemp = 0.0; \t% coefficients \ta = -8.01913564075E+00; \tb = 1.52644729419E+00; \ttemp = temp + a + b .* x_in; \ty = temp; ''' equation = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() generated = pyeq3.outputSourceCodeService().GetOutputSourceCodeMATLAB( equation, inDigitsOfPrecisionString='11') self.assertEqual(generated, generatedShouldBe)
def test_SolveUsingSimplex_3D(self): coefficientsShouldBe = numpy.array([0.28658383, -0.90215775, 1.15483864]) model = pyeq3.Models_3D.Polynomial.Linear('SSQABS') model.estimatedCoefficients = numpy.array([1.0, 1.0, 1.0]) # starting values for the simplex solver pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_3D, model, False) coefficients = pyeq3.solverService().SolveUsingSimplex(model) self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_SolveUsingDE_3D(self): coefficientsShouldBe = numpy.array([-2.05105972, -0.49194959, 1.77817475]) model = pyeq3.Models_3D.UserDefinedFunction.UserDefinedFunction('SSQABS', 'Default', 'a + b*X + c*Y') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_3D_small, model, False) coefficients = pyeq3.solverService().SolveUsingDE(model) fittingTarget = model.CalculateAllDataFittingTarget(coefficients) self.assertTrue(fittingTarget <= 0.1)
def SetParametersAndFit(inEquation, inPrintStatus): # utility function global globalDataCache global globalReducedDataCache global globalRawData inEquation.dataCache = globalDataCache if inEquation.dataCache.allDataCacheDictionary == {}: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( globalRawData, inEquation, False) inEquation.dataCache.CalculateNumberOfReducedDataPoints(inEquation) if inEquation.numberOfReducedDataPoints in globalReducedDataCache: inEquation.dataCache.reducedDataCacheDictionary = globalReducedDataCache[ inEquation.numberOfReducedDataPoints] else: inEquation.dataCache.reducedDataCacheDictionary = {} try: # check for number of coefficients > number of data points to be fitted if len(inEquation.GetCoefficientDesignators()) > len( inEquation.dataCache.allDataCacheDictionary['DependentData']): return None # check for functions requiring non-zero nor non-negative data such as 1/x, etc. if inEquation.ShouldDataBeRejected(inEquation): return None if inPrintStatus: print('Process ID', str(os.getpid()), 'Fitting', inEquation.__module__, "'" + inEquation.GetDisplayName() + "'") inEquation.Solve() if inEquation.numberOfReducedDataPoints not in globalReducedDataCache: globalReducedDataCache[ inEquation. numberOfReducedDataPoints] = inEquation.dataCache.reducedDataCacheDictionary target = inEquation.CalculateAllDataFittingTarget( inEquation.solvedCoefficients) if target > 1.0E290: # error too large return None except: print("Exception in " + inEquation.__class__.__name__ + '\n' + str(sys.exc_info()[0]) + '\n' + str(sys.exc_info()[1]) + '\n') return None t0 = copy.deepcopy(inEquation.__module__) t1 = copy.deepcopy(inEquation.__class__.__name__) t2 = copy.deepcopy( inEquation.extendedVersionHandler.__class__.__name__.split('_')[1]) t3 = copy.deepcopy(target) t4 = copy.deepcopy(inEquation.solvedCoefficients) t5 = copy.deepcopy(inEquation.polyfunctional2DFlags) t6 = copy.deepcopy(inEquation.xPolynomialOrder) t7 = copy.deepcopy(inEquation.rationalNumeratorFlags) t8 = copy.deepcopy(inEquation.rationalDenominatorFlags) return [t0, t1, t2, t3, t4, t5, t6, t7, t8]
def test_SplineSolve_3D(self): resultShouldBe = (numpy.array( [0.607, 0.607, 0.607, 3.017, 3.017, 3.017]), numpy.array([1.984, 1.984, 1.984, 3.153, 3.153, 3.153]), numpy.array([ 2.33418963, 1.80079612, 5.07902936, 0.54445029, 1.04110843, 2.14180324, 0.26992805, 0.39148852, 0.8177307 ])) model = pyeq3.Models_3D.Spline.Spline(inSmoothingFactor=1.0, inXOrder=2, inYOrder=2) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( model.exampleData, model, False) result = model.Solve() self.assertTrue( numpy.allclose(result[0], resultShouldBe[0], rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(result[1], resultShouldBe[1], rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(result[2], resultShouldBe[2], rtol=1.0E-06, atol=1.0E-300))
def test_SolveUsingODR_3D(self): coefficientsShouldBe = numpy.array([-0.04925, -0.90509, 1.28076]) model = pyeq3.Models_3D.Polynomial.Linear('ODR') model.estimatedCoefficients = numpy.array([0.2, -1.0, 1.0]) # starting values for the ODR solver pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_3D, model, False) coefficients = pyeq3.solverService().SolveUsingODR(model) self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-03, atol=1.0E-300))
def test_SolveUsingLevenbergMarquardt_2D(self): coefficientsShouldBe = numpy.array([-8.01913565, 1.5264473]) model = pyeq3.Models_2D.Polynomial.Linear('SSQABS') model.estimatedCoefficients = numpy.array([-4.0, 2.0]) # starting values for the simplex solver pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingSelectedAlgorithm(model, inAlgorithmName="Levenberg-Marquardt") self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_SolveUsingSpline_2D(self): knotPointsShouldBe = numpy.array( [5.357, 5.357, 5.357, 5.357, 9.861, 9.861, 9.861, 9.861]) coefficientsShouldBe = numpy.array([ 0.38297001, 1.95535226, 4.59605664, 7.16162379, 0.0, 0.0, 0.0, 0.0 ]) testEvaluationShouldBe = numpy.array([4.02361487093]) model = pyeq3.Models_2D.Spline.Spline(inSmoothingFactor=1.0, inXOrder=3) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, model, False) fittedParameters = pyeq3.solverService().SolveUsingSpline(model) # example of later using the saved spline knot points and coefficients unFittedSpline = scipy.interpolate.fitpack2.UnivariateSpline( model.dataCache.allDataCacheDictionary['X'], model.dataCache.allDataCacheDictionary['DependentData'], s=model.smoothingFactor, k=model.xOrder) unFittedSpline._eval_args = fittedParameters testEvaluation = unFittedSpline(numpy.array([8.0])) self.assertTrue( numpy.allclose(testEvaluation, testEvaluationShouldBe, rtol=1.0E-10, atol=1.0E-300)) self.assertTrue( numpy.equal(fittedParameters[0], knotPointsShouldBe).all()) self.assertTrue( numpy.allclose(fittedParameters[1], coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def SetParametersAndFit(equationString, inFittingTargetString, inExtendedVersionString, inTextData): # individual cluster nodes must be able to import pyeq3 import pyeq3 exec('equation = ' + equationString +'("' + inFittingTargetString + '", "' + inExtendedVersionString + '")') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(inTextData, equation, False) try: # check for number of coefficients > number of data points to be fitted if len(equation.GetCoefficientDesignators()) > len(equation.dataCache.allDataCacheDictionary['DependentData']): return None # check for functions requiring non-zero nor non-negative data such as 1/x, etc. if equation.ShouldDataBeRejected(equation): return None equation.Solve() fittedTarget = equation.CalculateAllDataFittingTarget(equation.solvedCoefficients) if fittedTarget > 1.0E290: # error too large return None except: return None return [fittedTarget, equation.GetDisplayName(), equation.solvedCoefficients, equationString, inExtendedVersionString]
def test_GenerationOf_PYTHON(self): generatedShouldBe = '''# To the best of my knowledge this code is correct. # If you find any errors or problems please contact # me directly using [email protected]. # # James import math # Fitting target: lowest sum of squared absolute error # Fitting target value = 0.223837322455 def Polynomial_Linear_model(x_in): temp = 0.0 # coefficients a = -8.01913564075E+00 b = 1.52644729419E+00 temp += a + b * x_in return temp ''' equation = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() generated = pyeq3.outputSourceCodeService().GetOutputSourceCodePYTHON( equation, inDigitsOfPrecisionString='11') self.assertEqual(generated, generatedShouldBe)
def test_GenerationOf_CPP(self): generatedShouldBe = '''// To the best of my knowledge this code is correct. // If you find any errors or problems please contact // me directly using [email protected]. // // James #include <math.h> // Fitting target: lowest sum of squared absolute error // Fitting target value = 0.223837322455 double Polynomial_Linear_model(double x_in) { double temp; temp = 0.0; // coefficients double a = -8.01913564075E+00; double b = 1.52644729419E+00; temp += a + b * x_in; return temp; } ''' equation = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() generated = pyeq3.outputSourceCodeService().GetOutputSourceCodeCPP( equation, inDigitsOfPrecisionString='11') self.assertEqual(generated, generatedShouldBe)
def OnFit_3D(self): textData = self.text_3D.get("1.0", tk.END) equationSelection = dfc.exampleEquationList_3D[self.equationSelect_3D.get()] fittingTargetSelection = dfc.fittingTargetList[self.fittingTargetSelect_3D.get()] # the GUI's fitting target string contains what we need - extract it fittingTarget = fittingTargetSelection.split('(')[1].split(')')[0] if equationSelection == 'Linear Polynomial': self.equation = pyeq3.Models_3D.Polynomial.Linear(fittingTarget) if equationSelection == 'Full Quadratic Polynomial': self.equation = pyeq3.Models_3D.Polynomial.FullQuadratic(fittingTarget) if equationSelection == 'Full Cubic Polynomial': self.equation = pyeq3.Models_3D.Polynomial.FullCubic(fittingTarget) if equationSelection == 'Monkey Saddle A': self.equation = pyeq3.Models_3D.Miscellaneous.MonkeySaddleA(fittingTarget) if equationSelection == 'Gaussian Curvature Of Whitneys Umbrella A': self.equation = pyeq3.Models_3D.Miscellaneous.GaussianCurvatureOfWhitneysUmbrellaA(fittingTarget) if equationSelection == 'NIST Nelson Autolog': self.equation = pyeq3.Models_3D.NIST.NIST_NelsonAutolog(fittingTarget) if equationSelection == 'Custom Polynomial One': self.equation = pyeq3.Models_3D.Polynomial.UserSelectablePolynomial(fittingTarget, "Default", 3, 1) # convert text to numeric data checking for log of negative numbers, etc. try: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(textData, self.equation, False) except: tk_mbox.showerror("Error", self.equation.reasonWhyDataRejected) return # check for number of coefficients > number of data points to be fitted coeffCount = len(self.equation.GetCoefficientDesignators()) dataCount = len(self.equation.dataCache.allDataCacheDictionary['DependentData']) if coeffCount > dataCount: tk_mbox.showerror("Error", "This equation requires a minimum of " + str(coeffCount) + " data points, you have supplied " + repr(dataCount) + ".") return # Now the status dialog is used. Disable fitting buttons until thread completes self.buttonFit_2D.config(state=tk.DISABLED) self.buttonFit_3D.config(state=tk.DISABLED) # create simple topl-level text dialog to display status as fitting progresses # when the fitting thread completes, it will close the status box self.statusBox = tk.Toplevel() self.statusBox.title("Fitting Status") self.statusBox.text = tk.Text(self.statusBox) self.statusBox.text.pack() # in tkinter the status box must be manually centered self.statusBox.update_idletasks() width = self.statusBox.winfo_width() height = self.statusBox.winfo_height() x = (self.statusBox.winfo_screenwidth() // 2) - (width // 2) # integer division y = (self.statusBox.winfo_screenheight() // 2) - (height // 2) # integer division self.statusBox.geometry('{}x{}+{}+{}'.format(width, height, x, y)) # thread will automatically start to run # "status update" handler will re-enable buttons self.fittingWorkerThread = FittingThread.FittingThread(self, self.equation)
def OnFit_3D(self): textData = self.text_3D.get("1.0", tk.END) moduleSelection = self.cb_Modules3D.get() equationSelection = self.cb_Equations3D.get() fittingTargetSelection = dfc.fittingTargetList[ self.fittingTargetSelect_3D.get()] # the GUI's fitting target string contains what we need - extract it fittingTarget = fittingTargetSelection.split('(')[1].split(')')[0] item = dfc.eq_od3D[moduleSelection][equationSelection] eqString = 'pyeq3.Models_3D.' + moduleSelection + '.' + item[ 0] + "('" + fittingTarget + "','" + item[1] + "')" self.equation = eval(eqString) # convert text to numeric data checking for log of negative numbers, etc. try: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( textData, self.equation, False) except: tk_mbox.showerror("Error", self.equation.reasonWhyDataRejected) return # check for number of coefficients > number of data points to be fitted coeffCount = len(self.equation.GetCoefficientDesignators()) dataCount = len( self.equation.dataCache.allDataCacheDictionary['DependentData']) if coeffCount > dataCount: tk_mbox.showerror( "Error", "This equation requires a minimum of " + str(coeffCount) + " data points, you have supplied " + repr(dataCount) + ".") return # Now the status dialog is used. Disable fitting buttons until thread completes self.buttonFit_2D.config(state=tk.DISABLED) self.buttonFit_3D.config(state=tk.DISABLED) # create simple top-level text dialog to display status as fitting progresses # when the fitting thread completes, it will close the status box self.statusBox = tk.Toplevel() self.statusBox.title("Fitting Status") self.statusBox.text = tk.Text(self.statusBox) self.statusBox.text.pack() # in tkinter the status box must be manually centered self.statusBox.update_idletasks() width = self.statusBox.winfo_width() height = self.statusBox.winfo_height() x = (self.statusBox.winfo_screenwidth() // 2) - (width // 2 ) # integer division y = (self.statusBox.winfo_screenheight() // 2) - (height // 2 ) # integer division self.statusBox.geometry('{}x{}+{}+{}'.format(width, height, x, y)) # thread will automatically start to run # "status update" handler will re-enable buttons self.fittingWorkerThread = FittingThread.FittingThread( self, self.equation)
def test_SolveUsingDE_3D(self): coefficientsShouldBe = numpy.array( [-2.05105972, -0.49194959, 1.77817475]) model = pyeq3.Models_3D.UserDefinedFunction.UserDefinedFunction( 'SSQABS', 'Default', 'a + b*X + c*Y') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_3D_small, model, False) coefficients = pyeq3.solverService().SolveUsingDE(model) fittingTarget = model.CalculateAllDataFittingTarget(coefficients) self.assertTrue(fittingTarget <= 0.1)
def test_UserDefinedFunctionSolve_SSQABS_2D(self): resultShouldBe = numpy.array([-7.88180304, 1.51245438]) model = pyeq3.Models_2D.UserDefinedFunction.UserDefinedFunction( 'SSQABS', 'Default', 'm*X + b') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D_small, model, False) result = model.Solve() self.assertTrue( numpy.allclose(result, resultShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_UserDefinedFunctionSolve_3D(self): resultShouldBe = numpy.array([-2.46874698, -0.43649152, 1.88125938]) model = pyeq3.Models_3D.UserDefinedFunction.UserDefinedFunction( 'SSQABS', 'Default', 'a + b*X + c*Y') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_3D_small, model, False) result = model.Solve() self.assertTrue( numpy.allclose(result, resultShouldBe, rtol=1.0E-06, atol=1.0E-300))
def OnFitDistributions(self): # get a list of the selected statistical distribution names selectedDistributions = [ self.distListBox.get(idx) for idx in self.distListBox.curselection() ] if len(selectedDistributions) < 1: tk_mbox.showerror( "Error", "You have not selected any statistical distributions.") return # convert text to numeric data checking for log of negative numbers, etc. textData = self.text_1D.get("1.0", tk.END) self.equationBase = pyeq3.IModel.IModel() self.equationBase._dimensionality = 1 pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( textData, self.equationBase, False) self.rawData = self.equationBase.dataCache.allDataCacheDictionary[ 'IndependentData'][0] dataCount = len(self.rawData) if dataCount < 2: tk_mbox.showerror( "Error", "A minimum of two data points is needed, you have supplied " + repr(dataCount) + ".") return # the sort order for results sortOrderString = self.sortOrderStringVar.get() # Now the status dialog is used. Disable fitting button until thread completes self.buttonFitDistributions.config(state=tk.DISABLED) # create simple top-level text dialog to display status as fitting progresses # when the fitting thread completes, it will close the status box self.statusBox = tk.Toplevel() self.statusBox.title("Fitting Status") self.statusBox.text = tk.Text(self.statusBox) self.statusBox.text.pack() # in tkinter the status box must be manually centered self.statusBox.update_idletasks() width = self.statusBox.winfo_width() height = self.statusBox.winfo_height() x = (self.statusBox.winfo_screenwidth() // 2) - (width // 2 ) # integer division y = (self.statusBox.winfo_screenheight() // 2) - (height // 2 ) # integer division self.statusBox.geometry('{}x{}+{}+{}'.format(width, height, x, y)) # thread will automatically start to run # "status update" handler will re-enable fitting button self.fittingWorkerThread = FittingThread.FittingThread( self, self.rawData, selectedDistributions, sortOrderString)
def test_SplineSolve_2D(self): resultShouldBe = (numpy.array([5.357, 5.357, 5.357, 5.357, 9.861, 9.861, 9.861, 9.861]), numpy.array([0.38297001, 1.95535226, 4.59605664, 7.16162379, 0.0, 0.0, 0.0, 0.0]), 3 ) model = pyeq3.Models_2D.Spline.Spline(inSmoothingFactor = 1.0, inXOrder = 3) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(model.exampleData, model, False) result = model.Solve() self.assertTrue(numpy.allclose(result[0], resultShouldBe[0], rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(result[1], resultShouldBe[1], rtol=1.0E-06, atol=1.0E-300)) self.assertEqual(result[2], resultShouldBe[2])
def test_SplineSolve_3D(self): resultShouldBe = (numpy.array([0.607, 0.607, 0.607, 3.017, 3.017, 3.017]), numpy.array([1.984, 1.984, 1.984, 3.153, 3.153, 3.153]), numpy.array([2.33418963, 1.80079612, 5.07902936, 0.54445029, 1.04110843, 2.14180324, 0.26992805, 0.39148852, 0.8177307]) ) model = pyeq3.Models_3D.Spline.Spline(inSmoothingFactor = 1.0, inXOrder = 2, inYOrder = 2) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(model.exampleData, model, False) result = model.Solve() self.assertTrue(numpy.allclose(result[0], resultShouldBe[0], rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(result[1], resultShouldBe[1], rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(result[2], resultShouldBe[2], rtol=1.0E-06, atol=1.0E-300))
def test_SolveUsingODR_2D(self): coefficientsShouldBe = numpy.array([-8.04624, 1.53032]) model = pyeq3.Models_2D.Polynomial.Linear('ODR') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingODR(model) self.assertTrue( numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-03, atol=1.0E-300))
def fitEquationUsingDispyCluster(inEquationString, inFittingTargetString, inExtendedVersionString, inTextData): # individual cluster nodes must be able to import pyeq3 import pyeq3 equation = eval(inEquationString +'("' + inFittingTargetString + '", "' + inExtendedVersionString + '")') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(inTextData, equation, False) equation.Solve() fittedTarget = equation.CalculateAllDataFittingTarget(equation.solvedCoefficients) # this result list allows easy sorting of multiple results later return [fittedTarget, inEquationString, equation.solvedCoefficients]
def test_SolveUsingLinear_2D(self): coefficientsShouldBe = numpy.array( [-8.0191356407516956E+00, 1.5264472941853220E+00]) model = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingLinear(model) self.assertTrue( numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-10, atol=1.0E-300))
def test_ExponentialSensitivity_2D(self): coefficientsShouldBe = numpy.array([2.0, 0.1, -3000.0]) model = pyeq3.Models_2D.Exponential.Exponential('SSQABS', 'Offset') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataForExponentialSensitivityTest, model, False) model.Solve() self.assertTrue( numpy.allclose(model.solvedCoefficients, coefficientsShouldBe, rtol=1.0E-10, atol=1.0E-300))
def fitEquationUsingDispyCluster(inEquationString, inFittingTargetString, inExtendedVersionString, inTextData): # individual cluster nodes must be able to import pyeq3 import pyeq3 exec('equation = ' + inEquationString +'("' + inFittingTargetString + '", "' + inExtendedVersionString + '")') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(inTextData, equation, False) equation.Solve() fittedTarget = equation.CalculateAllDataFittingTarget(equation.solvedCoefficients) # this result list allows easy sorting of multiple results later return [fittedTarget, inEquationString, equation.solvedCoefficients]
def test_SolveUsingDE_2D(self): coefficientsShouldBe = numpy.array([-7.92223965, 1.51863709]) model = pyeq3.Models_2D.UserDefinedFunction.UserDefinedFunction( 'SSQABS', 'Default', 'm*X + b') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D_small, model, False) coefficients = pyeq3.solverService().SolveUsingDE(model) self.assertTrue( numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-05, atol=1.0E-300))
def test_SolveUsingODR_3D(self): coefficientsShouldBe = numpy.array([-0.04925, -0.90509, 1.28076]) model = pyeq3.Models_3D.Polynomial.Linear('ODR') model.estimatedCoefficients = numpy.array( [0.2, -1.0, 1.0]) # starting values for the ODR solver pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_3D, model, False) coefficients = pyeq3.solverService().SolveUsingODR(model) self.assertTrue( numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-03, atol=1.0E-300))
def test_SolveUsingSimplex_SSQABS_2D(self): coefficientsShouldBe = numpy.array([-8.01913562, 1.52644729]) model = pyeq3.Models_2D.Polynomial.Linear('SSQABS') model.estimatedCoefficients = numpy.array( [1.0, 1.0]) # starting values for the simplex solver pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingSimplex(model) self.assertTrue( numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_UserDefinedFunction_2D(self): coefficientsShouldBe = numpy.array([3.28686108e-04, 1.30583728]) functionString = 'Scale * exp(X) + offset' model = pyeq3.Models_2D.UserDefinedFunction.UserDefinedFunction( inUserFunctionString=functionString) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, model, False) model.Solve() self.assertTrue( numpy.allclose(model.solvedCoefficients, coefficientsShouldBe, rtol=1.0E-8, atol=1.0E-300))
def SetParametersAndFit(inEquation, inPrintStatus): # utility function global globalDataCache global globalReducedDataCache global globalRawData inEquation.dataCache = globalDataCache if inEquation.dataCache.allDataCacheDictionary == {}: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(globalRawData, inEquation, False) inEquation.dataCache.CalculateNumberOfReducedDataPoints(inEquation) if inEquation.numberOfReducedDataPoints in globalReducedDataCache: inEquation.dataCache.reducedDataCacheDictionary = globalReducedDataCache[inEquation.numberOfReducedDataPoints] else: inEquation.dataCache.reducedDataCacheDictionary = {} try: # check for number of coefficients > number of data points to be fitted if len(inEquation.GetCoefficientDesignators()) > len(inEquation.dataCache.allDataCacheDictionary['DependentData']): return None # check for functions requiring non-zero nor non-negative data such as 1/x, etc. if inEquation.ShouldDataBeRejected(inEquation): return None if inPrintStatus: print('Process ID', str(os.getpid()), 'Fitting', inEquation.__module__, "'" + inEquation.GetDisplayName() + "'") inEquation.Solve() if inEquation.numberOfReducedDataPoints not in globalReducedDataCache: globalReducedDataCache[inEquation.numberOfReducedDataPoints] = inEquation.dataCache.reducedDataCacheDictionary target = inEquation.CalculateAllDataFittingTarget(inEquation.solvedCoefficients) if target > 1.0E290: # error too large return None except: print("Exception in " + inEquation.__class__.__name__ + '\n' + str(sys.exc_info()[0]) + '\n' + str(sys.exc_info()[1]) + '\n') return None t0 = copy.deepcopy(inEquation.__module__) t1 = copy.deepcopy(inEquation.__class__.__name__) t2 = copy.deepcopy(inEquation.extendedVersionHandler.__class__.__name__.split('_')[1]) t3 = copy.deepcopy(target) t4 = copy.deepcopy(inEquation.solvedCoefficients) t5 = copy.deepcopy(inEquation.polyfunctional2DFlags) t6 = copy.deepcopy(inEquation.xPolynomialOrder) t7 = copy.deepcopy(inEquation.rationalNumeratorFlags) t8 = copy.deepcopy(inEquation.rationalDenominatorFlags) return [t0,t1,t2,t3,t4,t5,t6,t7,t8]
def test_SolveUsingLevenbergMarquardt_2D(self): coefficientsShouldBe = numpy.array([-8.01913565, 1.5264473]) model = pyeq3.Models_2D.Polynomial.Linear('SSQABS') model.estimatedCoefficients = numpy.array( [-4.0, 2.0]) # starting values for the simplex solver pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingSelectedAlgorithm( model, inAlgorithmName="Levenberg-Marquardt") self.assertTrue( numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_SolveUsingLinear_3D(self): coefficientsShouldBe = numpy.array([ 2.8658381589774945E-01, -9.0215775175410395E-01, 1.1548386445491325E+00 ]) model = pyeq3.Models_3D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_3D, model, False) coefficients = pyeq3.solverService().SolveUsingLinear(model) self.assertTrue( numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-10, atol=1.0E-300))
def test_SolveUsingSpline_2D(self): knotPointsShouldBe = numpy.array([5.357, 5.357, 5.357, 5.357, 9.861, 9.861, 9.861, 9.861]) coefficientsShouldBe = numpy.array([ 0.38297001, 1.95535226, 4.59605664, 7.16162379, 0.0, 0.0, 0.0, 0.0]) testEvaluationShouldBe = numpy.array([4.02361487093]) model = pyeq3.Models_2D.Spline.Spline(inSmoothingFactor = 1.0, inXOrder = 3) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, model, False) fittedParameters = pyeq3.solverService().SolveUsingSpline(model) # example of later using the saved spline knot points and coefficients unFittedSpline = scipy.interpolate.fitpack2.UnivariateSpline(model.dataCache.allDataCacheDictionary['X'], model.dataCache.allDataCacheDictionary['DependentData'], s=model.smoothingFactor, k=model.xOrder) unFittedSpline._eval_args = fittedParameters testEvaluation = unFittedSpline(numpy.array([8.0])) self.assertTrue(numpy.allclose(testEvaluation, testEvaluationShouldBe, rtol=1.0E-10, atol=1.0E-300)) self.assertTrue(numpy.equal(fittedParameters[0], knotPointsShouldBe).all()) self.assertTrue(numpy.allclose(fittedParameters[1], coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def OnFit2D(self, evt): textData = str(self.text_2D.GetValue()) equationSelection = self.rbEqChoice_2D.GetStringSelection() fittingTargetSelection = self.rbFittingTargetChoice_2D.GetStringSelection() # the GUI's fitting target string contains what we need - extract it fittingTarget = fittingTargetSelection.split('(')[1].split(')')[0] if equationSelection == 'Linear Polynomial': self.equation = pyeq3.Models_2D.Polynomial.Linear(fittingTarget) if equationSelection == 'Quadratic Polynomial': self.equation = pyeq3.Models_2D.Polynomial.Quadratic(fittingTarget) if equationSelection == 'Cubic Polynomial': self.equation = pyeq3.Models_2D.Polynomial.Cubic(fittingTarget) if equationSelection == 'Witch Of Maria Agnesi A': self.equation = pyeq3.Models_2D.Miscellaneous.WitchOfAgnesiA(fittingTarget) if equationSelection == 'VanDeemter Chromatography': self.equation = pyeq3.Models_2D.Engineering.VanDeemterChromatography(fittingTarget) if equationSelection == 'Gamma Ray Angular Distribution (degrees) B': self.equation = pyeq3.Models_2D.LegendrePolynomial.GammaRayAngularDistributionDegreesB(fittingTarget) if equationSelection == 'Exponential With Offset': self.equation = pyeq3.Models_2D.Exponential.Exponential(fittingTarget, 'Offset') # convert text to numeric data checking for log of negative numbers, etc. try: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(textData, self.equation, False) except: wx.MessageBox(self.equation.reasonWhyDataRejected, "Error") return # check for number of coefficients > number of data points to be fitted coeffCount = len(self.equation.GetCoefficientDesignators()) dataCount = len(self.equation.dataCache.allDataCacheDictionary['DependentData']) if coeffCount > dataCount: wx.MessageBox("This equation requires a minimum of " + str(coeffCount) + " data points, you have supplied " + repr(dataCount) + ".", "Error") return # Now the status dialog is used. Disable fitting buttons until thread completes self.btnFit2D.Disable() self.btnFit3D.Disable() self.statusBox.text.SetValue('') self.statusBox.Show() # hidden by OnThreadStatus() when thread completes # thread will automatically start to tun self.fittingWorkerThread = CustomThreads.FittingThread(self, self.equation)
def OnFit3D(self, evt): textData = str(self.text_3D.GetValue()) equationSelection = self.rbEqChoice_3D.GetStringSelection() fittingTargetSelection = self.rbFittingTargetChoice_3D.GetStringSelection() # the GUI's fitting target string contains what we need - extract it fittingTarget = fittingTargetSelection.split('(')[1].split(')')[0] if equationSelection == 'Linear Polynomial': self.equation = pyeq3.Models_3D.Polynomial.Linear(fittingTarget) if equationSelection == 'Full Quadratic Polynomial': self.equation = pyeq3.Models_3D.Polynomial.FullQuadratic(fittingTarget) if equationSelection == 'Full Cubic Polynomial': self.equation = pyeq3.Models_3D.Polynomial.FullCubic(fittingTarget) if equationSelection == 'Monkey Saddle A': self.equation = pyeq3.Models_3D.Miscellaneous.MonkeySaddleA(fittingTarget) if equationSelection == 'Gaussian Curvature Of Whitneys Umbrella A': self.equation = pyeq3.Models_3D.Miscellaneous.GaussianCurvatureOfWhitneysUmbrellaA(fittingTarget) if equationSelection == 'NIST Nelson Autolog': self.equation = pyeq3.Models_3D.NIST.NIST_NelsonAutolog(fittingTarget) if equationSelection == 'Custom Polynomial One': self.equation = pyeq3.Models_3D.Polynomial.UserSelectablePolynomial(fittingTarget, "Default", 3, 1) # convert text to numeric data checking for log of negative numbers, etc. try: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(textData, self.equation, False) except: wx.MessageBox(self.equation.reasonWhyDataRejected, "Error") return # check for number of coefficients > number of data points to be fitted coeffCount = len(self.equation.GetCoefficientDesignators()) dataCount = len(self.equation.dataCache.allDataCacheDictionary['DependentData']) if coeffCount > dataCount: wx.MessageBox("This equation requires a minimum of " + str(coeffCount) + " data points, you have supplied " + repr(dataCount) + ".", "Error") return # Now the status dialog is used. Disable fitting buttons until thread completes self.btnFit2D.Disable() self.btnFit3D.Disable() self.statusBox.text.SetValue('') self.statusBox.Show() # hidden by OnThreadStatus() when thread completes # thread will automatically start to run self.fittingWorkerThread = CustomThreads.FittingThread(self, self.equation)
def test_SolveUsingSpline_3D(self): xKnotPointsShouldBe = numpy.array([0.607, 0.607, 0.607, 3.017, 3.017, 3.017]) yKnotPointsShouldBe = numpy.array([1.984, 1.984, 1.984, 3.153, 3.153, 3.153]) coefficientsShouldBe = numpy.array([2.33418963, 1.80079612, 5.07902936, 0.54445029, 1.04110843, 2.14180324, 0.26992805, 0.39148852, 0.8177307]) testEvaluationShouldBe = numpy.array([0.76020577997]) model = pyeq3.Models_3D.Spline.Spline(inSmoothingFactor = 1.0, inXOrder = 2, inYOrder = 2) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_3D, model, False) fittedParameters = pyeq3.solverService().SolveUsingSpline(model) # example of later using the saved spline knot points and coefficients unFittedSpline = scipy.interpolate.fitpack2.SmoothBivariateSpline(model.dataCache.allDataCacheDictionary['X'], model.dataCache.allDataCacheDictionary['Y'], model.dataCache.allDataCacheDictionary['DependentData'], s=model.smoothingFactor, kx=model.xOrder, ky=model.yOrder) unFittedSpline.tck = fittedParameters testEvaluation = unFittedSpline.ev(2.5, 2.5) self.assertTrue(numpy.allclose(testEvaluation, testEvaluationShouldBe, rtol=1.0E-10, atol=1.0E-300)) self.assertTrue(numpy.equal(fittedParameters[0], xKnotPointsShouldBe).all()) self.assertTrue(numpy.equal(fittedParameters[1], yKnotPointsShouldBe).all()) self.assertTrue(numpy.allclose(fittedParameters[2], coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_ExtendedVersion_Inverse_Exponential_2D(self): equation = pyeq3.Models_2D.Exponential.Exponential('SSQABS', 'Inverse') self.assertEqual(equation.extendedVersionHandler.__class__.__name__, 'ExtendedVersionHandler_Inverse') self.assertEqual(equation.GetDisplayHTML(), 'y = a * exp(bx)<br>y = x / y') self.assertEqual(equation.GetDisplayName(), 'Inverse Exponential') self.assertEqual(equation.GetCoefficientDesignators(), ['a', 'b']) self.assertEqual(len(equation.GetDataCacheFunctions()), 1) self.assertFalse(equation.CanLinearSolverBeUsedForSSQABS()) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() fittingTarget = equation.CalculateAllDataFittingTarget( equation.solvedCoefficients) self.assertTrue(fittingTarget <= 1.6)
def test_SolveUsingSpline_3D(self): xKnotPointsShouldBe = numpy.array( [0.607, 0.607, 0.607, 3.017, 3.017, 3.017]) yKnotPointsShouldBe = numpy.array( [1.984, 1.984, 1.984, 3.153, 3.153, 3.153]) coefficientsShouldBe = numpy.array([ 2.33418963, 1.80079612, 5.07902936, 0.54445029, 1.04110843, 2.14180324, 0.26992805, 0.39148852, 0.8177307 ]) testEvaluationShouldBe = numpy.array([0.76020577997]) model = pyeq3.Models_3D.Spline.Spline(inSmoothingFactor=1.0, inXOrder=2, inYOrder=2) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_3D, model, False) fittedParameters = pyeq3.solverService().SolveUsingSpline(model) # example of later using the saved spline knot points and coefficients unFittedSpline = scipy.interpolate.fitpack2.SmoothBivariateSpline( model.dataCache.allDataCacheDictionary['X'], model.dataCache.allDataCacheDictionary['Y'], model.dataCache.allDataCacheDictionary['DependentData'], s=model.smoothingFactor, kx=model.xOrder, ky=model.yOrder) unFittedSpline.tck = fittedParameters testEvaluation = unFittedSpline.ev(2.5, 2.5) self.assertTrue( numpy.allclose(testEvaluation, testEvaluationShouldBe, rtol=1.0E-10, atol=1.0E-300)) self.assertTrue( numpy.equal(fittedParameters[0], xKnotPointsShouldBe).all()) self.assertTrue( numpy.equal(fittedParameters[1], yKnotPointsShouldBe).all()) self.assertTrue( numpy.allclose(fittedParameters[2], coefficientsShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_ExtendedVersion_Asymptotic_Exponential_A_WithExponentialDecay_2D( self): equation = pyeq3.Models_2D.Exponential.AsymptoticExponentialA( 'SSQABS', 'Exponential Decay') self.assertEqual(equation.extendedVersionHandler.__class__.__name__, 'ExtendedVersionHandler_ExponentialDecay') self.assertEqual(equation.GetDisplayHTML(), 'y = 1.0 - a<sup>x</sup><br>y = y / (b * exp(x))') self.assertEqual(equation.GetDisplayName(), 'Asymptotic Exponential A With Exponential Decay') self.assertEqual(equation.GetCoefficientDesignators(), ['a', 'b']) self.assertEqual(len(equation.GetDataCacheFunctions()), 2) self.assertFalse(equation.CanLinearSolverBeUsedForSSQABS()) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( DataForUnitTests.asciiDataInColumns_2D, equation, False) equation.Solve() fittingTarget = equation.CalculateAllDataFittingTarget( equation.solvedCoefficients) self.assertTrue(fittingTarget <= 1.9)
def test_CalculateCoefficientAndFitStatisticsUsingSpline_2D(self): model_df_e_ShouldBe = 8.0 model_df_r_ShouldBe = 2.0 model_r2_ShouldBe = 0.999870240966 model_rmse_ShouldBe = 0.0270425329959 model_r2adj_ShouldBe = 0.999837801207 model_Fstat_ShouldBe = 30822.3699783 model_Fpv_ShouldBe = 3.33066907388e-16 model_ll_ShouldBe = 24.1054640542 model_aic_ShouldBe = -3.83735710076 model_bic_ShouldBe = -3.72884020818 model_cov_beta_ShouldBe = None model_sd_beta_ShouldBe = None model_tstat_beta_ShouldBe = None model_pstat_beta_ShouldBe = None model_ci_ShouldBe = None model = pyeq3.Models_2D.Spline.Spline(inSmoothingFactor = 1.0, inXOrder = 3) pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, model, False) pyeq3.solverService().SolveUsingSpline(model) model.CalculateModelErrors(model.solvedCoefficients, model.dataCache.allDataCacheDictionary) model.CalculateCoefficientAndFitStatistics() self.assertTrue(numpy.allclose(model.df_e, model_df_e_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.df_r, model_df_r_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.r2, model_r2_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.rmse, model_rmse_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.r2adj, model_r2adj_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.Fstat, model_Fstat_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.Fpv, model_Fpv_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.ll, model_ll_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.aic, model_aic_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.bic, model_bic_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertEqual(model.cov_beta, None) self.assertEqual(model.sd_beta, None) self.assertEqual(model.tstat_beta, None) self.assertEqual(model.pstat_beta, None) self.assertEqual(model.ci, None)
def test_CalculateCoefficientAndFitStatisticsUsingUserDefinedFunction_2D(self): model_df_e_ShouldBe = 9.0 model_df_r_ShouldBe = 1.0 model_r2_ShouldBe = 0.996389372503 model_rmse_ShouldBe = 00.142649386595 model_r2adj_ShouldBe = 0.99598819167 model_Fstat_ShouldBe = 2483.64151657 model_Fpv_ShouldBe = 2.64577248998e-12 model_ll_ShouldBe = 5.81269665017 model_aic_ShouldBe = -0.693217572758 model_bic_ShouldBe = -0.620872977703 model_cov_beta_ShouldBe = numpy.array([[ 1.93842855, -0.26398964], [-0.26398964, 0.03772113]]) model_sd_beta_ShouldBe = numpy.array([ 0.0482103, 0.00093816]) model_tstat_beta_ShouldBe = numpy.array([-36.52226166, 49.83614545]) model_pstat_beta_ShouldBe = numpy.array([4.28455049e-11, 2.64588351e-12]) model_ci_ShouldBe = numpy.array([[-8.5158339321793157, -7.5224373409719512], [1.4571589560702567, 1.595735631605572]]) model = pyeq3.Models_2D.UserDefinedFunction.UserDefinedFunction('SSQABS', 'Default', 'm*X + b') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(model.exampleData, model, False) model.Solve() model.CalculateModelErrors(model.solvedCoefficients, model.dataCache.allDataCacheDictionary) model.CalculateCoefficientAndFitStatistics() self.assertTrue(numpy.allclose(model.df_e, model_df_e_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.df_r, model_df_r_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.r2, model_r2_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.rmse, model_rmse_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.r2adj, model_r2adj_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.Fstat, model_Fstat_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.Fpv, model_Fpv_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.ll, model_ll_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.aic, model_aic_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.bic, model_bic_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.cov_beta, model_cov_beta_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.sd_beta, model_sd_beta_ShouldBe, rtol=1.0E-05, atol=1.0E-300)) # extra tolerance self.assertTrue(numpy.allclose(model.tstat_beta, model_tstat_beta_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.pstat_beta, model_pstat_beta_ShouldBe, rtol=1.0E-04, atol=1.0E-300)) self.assertTrue(numpy.allclose(model.ci, model_ci_ShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_UserDefinedFunctionSolve_SSQABS_2D(self): resultShouldBe = numpy.array([-7.88180304, 1.51245438]) model = pyeq3.Models_2D.UserDefinedFunction.UserDefinedFunction('SSQABS', 'Default', 'm*X + b') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D_small, model, False) result = model.Solve() self.assertTrue(numpy.allclose(result, resultShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_UserDefinedFunctionSolve_3D(self): resultShouldBe = numpy.array([-2.46874698, -0.43649152, 1.88125938]) model = pyeq3.Models_3D.UserDefinedFunction.UserDefinedFunction('SSQABS', 'Default', 'a + b*X + c*Y') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_3D_small, model, False) result = model.Solve() self.assertTrue(numpy.allclose(result, resultShouldBe, rtol=1.0E-06, atol=1.0E-300))
def test_SolveUsingDE_2D(self): coefficientsShouldBe = numpy.array([-7.92223965, 1.51863709]) model = pyeq3.Models_2D.UserDefinedFunction.UserDefinedFunction('SSQABS', 'Default', 'm*X + b') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D_small, model, False) coefficients = pyeq3.solverService().SolveUsingDE(model) self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-05, atol=1.0E-300))
rationalNumeratorFlags = bestResult[7] rationalDenominatorFlags = bestResult[8] # now instantiate the "best fit" equation based on the name stored in the result list if polyfunctional2DFlags: equation = eval(moduleName + "." + className + "('" + fittingTargetText + "', '" + extendedVersionHandlerName + "', " + str(polyfunctional2DFlags) + ")") elif polynomialOrderX != None: equation = eval(moduleName + "." + className + "('" + fittingTargetText + "', '" + extendedVersionHandlerName + "', " + str(polynomialOrderX) + ")") elif rationalNumeratorFlags and rationalDenominatorFlags: equation = eval(moduleName + "." + className + "('" + fittingTargetText + "', '" + extendedVersionHandlerName + "', " + str(rationalNumeratorFlags) + ", " + str(rationalDenominatorFlags) + ")") else: equation = eval(moduleName + "." + className + "('" + fittingTargetText + "', '" + extendedVersionHandlerName + "')") pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(globalRawData, equation, False) equation.fittingTarget = fittingTargetText equation.solvedCoefficients = solvedCoefficients equation.dataCache.FindOrCreateAllDataCache(equation) equation.CalculateModelErrors(equation.solvedCoefficients, equation.dataCache.allDataCacheDictionary) print() print('\"Best fit\" was', moduleName + "." + className) print('Fitting target value', equation.fittingTarget + ":", equation.CalculateAllDataFittingTarget(equation.solvedCoefficients)) if polyfunctional2DFlags: print() print('Polyfunctional flags:', polyfunctional2DFlags) print()
def test_SolveUsingLinear_2D(self): coefficientsShouldBe = numpy.array([-8.0191356407516956E+00, 1.5264472941853220E+00]) model = pyeq3.Models_2D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingLinear(model) self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-10, atol=1.0E-300))
def test_SolveUsingLinear_3D(self): coefficientsShouldBe = numpy.array([2.8658381589774945E-01, -9.0215775175410395E-01, 1.1548386445491325E+00]) model = pyeq3.Models_3D.Polynomial.Linear('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_3D, model, False) coefficients = pyeq3.solverService().SolveUsingLinear(model) self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-10, atol=1.0E-300))
def simplefitter_2D_NoFormDataValidation(): formTextData = request.form['textdata'] formEquation = request.form['equation'] formFittingTarget = request.form['target'] if formEquation == 'Linear': equation = pyeq3.Models_2D.Polynomial.Linear(formFittingTarget) elif formEquation == 'Quadratic': equation = pyeq3.Models_2D.Polynomial.Quadratic(formFittingTarget) elif formEquation == 'Cubic': equation = pyeq3.Models_2D.Polynomial.Cubic(formFittingTarget) elif formEquation == 'WitchA': equation = pyeq3.Models_2D.Miscellaneous.WitchOfAgnesiA(formFittingTarget) elif formEquation == 'VanDeemter': equation = pyeq3.Models_2D.Engineering.VanDeemterChromatography(formFittingTarget) elif formEquation == 'GammaRayDegreesB': equation = pyeq3.Models_2D.LegendrePolynomial.GammaRayAngularDistributionDegreesB(formFittingTarget) elif formEquation == 'ExponentialWithOffset': equation = pyeq3.Models_2D.Exponential.Exponential(formFittingTarget, 'Offset') # the name of the data here is from the form # check for functions requiring non-zero nor non-negative data such as 1/x, etc. try: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(formTextData, equation, False) except: return equation.reasonWhyDataRejected # check for number of coefficients > number of data points to be fitted coeffCount = len(equation.GetCoefficientDesignators()) dataCount = len(equation.dataCache.allDataCacheDictionary['DependentData']) if coeffCount > dataCount: return "This equation requires a minimum of " + repr(coeffCount) + " data points, you supplied " + repr(dataCount) + "." equation.Solve() equation.CalculateModelErrors(equation.solvedCoefficients, equation.dataCache.allDataCacheDictionary) equation.CalculateCoefficientAndFitStatistics() # save fit statistics to a text file fitStatisticsFilePath = "static/fitstatistics_2D.txt" # simplefitter_2D TextUtils.SaveCoefficientAndFitStatistics(fitStatisticsFilePath, equation) # save source code to a single text file, all available languages sourceCodeFilePath = "static/sourcecode_2D.html" # simplefitter_2D TextUtils.SaveSourceCode(sourceCodeFilePath, equation) # create graph graphFilePath = "static/model_and_scatterplot_2D.png" # simplefitter_2D title = "Example Of An HTML FORM Model" xAxisLabel = "X data" yAxisLabel = "Y data" GraphUtils.SaveModelScatterConfidence(graphFilePath, equation, title, xAxisLabel, yAxisLabel) absErrorPlotFilePath = "static/abs_error_2D.png" # simplefitter_2D title = "Absolute Error For An HTML FORM Model" GraphUtils.SaveAbsErrorScatterPlot(absErrorPlotFilePath, equation, title, yAxisLabel) absErrorHistFilePath = "static/abs_error_hist_2D.png" # simplefitter_2D title = "Absolute Error" GraphUtils.SaveDataHistogram(absErrorHistFilePath, equation.modelAbsoluteError, title) if equation.dataCache.DependentDataContainsZeroFlag != 1: percentErrorPlotFilePath = "static/per_error_2D.png" # simplefitter_2D title = "Percent Error For An HTML FORM Model" GraphUtils.SavePercentErrorScatterPlot(percentErrorPlotFilePath, equation, title, yAxisLabel) perErrorHistFilePath = "static/per_error_hist_2D.png" # simplefitter_2D title = "Percent Error" GraphUtils.SaveDataHistogram(perErrorHistFilePath, equation.modelPercentError, title) # generate HTML htmlToReturn = '' htmlToReturn += equation.GetDisplayName() + '<br><br>\n' htmlToReturn += equation.GetDisplayHTML() + '<br><br>\n' htmlToReturn += '<a href="' + fitStatisticsFilePath + '">Link to parameter and fit statistics</a><br><br>\n' htmlToReturn += '<a href="' + sourceCodeFilePath + '">Link to source code, all available languages</a><br><br>\n' htmlToReturn += '<img src="' + graphFilePath + '"> <br>\n' htmlToReturn += '<img src="' + absErrorPlotFilePath + '"><br>\n' htmlToReturn += '<img src="' + absErrorHistFilePath + '"><br>\n' if equation.dataCache.DependentDataContainsZeroFlag != 1: htmlToReturn += '<img src="' + percentErrorPlotFilePath + '"><br><br>\n' htmlToReturn += '<img src="' + perErrorHistFilePath + '"><br><br>\n' return '<html><body>' + htmlToReturn + '</body></html>'
if (extendedVersion == 'Offset') and ( equationClass[1].autoGenerateOffsetForm == False): continue equationInstance = equationClass[1](fittingTargetText, extendedVersion) if len(equationInstance.GetCoefficientDesignators() ) > smoothnessControl: continue equationInstance.dataCache = externalCache # re-use the external cache if equationInstance.dataCache.allDataCacheDictionary == {}: pyeq3.dataConvertorService( ).ConvertAndSortColumnarASCII(rawData, equationInstance, False) equationInstance.dataCache.CalculateNumberOfReducedDataPoints( equationInstance) if equationInstance.numberOfReducedDataPoints in reducedDataCache: equationInstance.dataCache.reducedDataCacheDictionary = reducedDataCache[ equationInstance.numberOfReducedDataPoints] else: equationInstance.dataCache.reducedDataCacheDictionary = {} SetParametersAndFit(equationInstance, resultList, True) if equationInstance.numberOfReducedDataPoints not in reducedDataCache: reducedDataCache[ equationInstance.
def test_ExponentialSensitivity_2D(self): coefficientsShouldBe = numpy.array([2.0, 0.1, -3000.0]) model = pyeq3.Models_2D.Exponential.Exponential('SSQABS', 'Offset') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataForExponentialSensitivityTest, model, False) model.Solve() self.assertTrue(numpy.allclose(model.solvedCoefficients, coefficientsShouldBe, rtol=1.0E-10, atol=1.0E-300))
import os, sys, inspect # ensure pyeq3 can be imported if -1 != sys.path[0].find('pyeq3-master'):raise Exception('Please rename git checkout directory from "pyeq3-master" to "pyeq3"') exampleFileDirectory = sys.path[0][:sys.path[0].rfind(os.sep)] pyeq3IimportDirectory = os.path.join(os.path.join(exampleFileDirectory, '..'), '..') if pyeq3IimportDirectory not in sys.path: sys.path.append(pyeq3IimportDirectory) import pyeq3 # see IModel.fittingTargetDictionary equation = pyeq3.Models_3D.BioScience.HighLowAffinityIsotopeDisplacement('SSQABS') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(equation.exampleData, equation, False) # Note that all coefficients are set with estimated values equation.estimatedCoefficients = [2.0, 3.0E13] equation.Solve() ########################################################## print(equation.GetDisplayName(), str(equation.GetDimensionality()) + "D") print(equation.fittingTargetDictionary[equation.fittingTarget], '=', equation.CalculateAllDataFittingTarget(equation.solvedCoefficients)) print("Fitted Parameters:")
def test_SolveUsingODR_2D(self): coefficientsShouldBe = numpy.array([-8.04624, 1.53032]) model = pyeq3.Models_2D.Polynomial.Linear('ODR') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(DataForUnitTests.asciiDataInColumns_2D, model, False) coefficients = pyeq3.solverService().SolveUsingODR(model) self.assertTrue(numpy.allclose(coefficients, coefficientsShouldBe, rtol=1.0E-03, atol=1.0E-300))
def simplefitter_3D_NoFormDataValidation(): formTextData = request.form['textdata'] formEquation = request.form['equation'] formFittingTarget = request.form['target'] if formEquation == 'Linear': equation = pyeq3.Models_3D.Polynomial.Linear(formFittingTarget) elif formEquation == 'FullQuadratic': equation = pyeq3.Models_3D.Polynomial.FullQuadratic(formFittingTarget) elif formEquation == 'FullCubic': equation = pyeq3.Models_3D.Polynomial.FullCubic(formFittingTarget) elif formEquation == 'MonkeySaddleA': equation = pyeq3.Models_3D.Miscellaneous.MonkeySaddleA(formFittingTarget) elif formEquation == 'GaussianCurvatureOfWhitneysUmbrellaA': equation = pyeq3.Models_3D.Miscellaneous.GaussianCurvatureOfWhitneysUmbrellaA(formFittingTarget) elif formEquation == 'NIST_NelsonAutolog': equation = pyeq3.Models_3D.NIST.NIST_NelsonAutolog(formFittingTarget) elif formEquation == 'CustomPolynomialOne': # X order 3, Y order 1 in this example - passed as integers equation = pyeq3.Models_3D.Polynomial.UserSelectablePolynomial(formFittingTarget, "Default", 3, 1) # the name of the data here is from the form # check for functions requiring non-zero nor non-negative data such as 1/x, etc. try: pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(formTextData, equation, False) except: return equation.reasonWhyDataRejected # check for number of coefficients > number of data points to be fitted coeffCount = len(equation.GetCoefficientDesignators()) dataCount = len(equation.dataCache.allDataCacheDictionary['DependentData']) if coeffCount > dataCount: return "This equation requires a minimum of " + repr(coeffCount) + " data points, you supplied " + repr(dataCount) + "." equation.Solve() equation.CalculateModelErrors(equation.solvedCoefficients, equation.dataCache.allDataCacheDictionary) equation.CalculateCoefficientAndFitStatistics() # save fit statistics to a text file fitStatisticsFilePath = "static/fitstatistics_3D.txt" # simplefitter_3D TextUtils.SaveCoefficientAndFitStatistics(fitStatisticsFilePath, equation) # save source code to a single text file, all available languages sourceCodeFilePath = "static/sourcecode_3D.html" # simplefitter_3D TextUtils.SaveSourceCode(sourceCodeFilePath, equation) # create graphs graphFilePath_Surface = "static/surface.png" # surface plot graphFilePath_Contour = "static/contour.png" # contour plot surfaceTitle = "Example Surface Plot" contourTitle = "Example Contour Plot" xAxisLabel = "X data" yAxisLabel = "Y data" zAxisLabel = "Z data" GraphUtils.SurfaceAndContourPlots(graphFilePath_Surface, graphFilePath_Contour, equation, surfaceTitle, contourTitle, xAxisLabel, yAxisLabel, zAxisLabel) absErrorPlotFilePath = "static/abs_error_3D.png" # simplefitter_3D title = "Absolute Error For An HTML FORM Model" GraphUtils.SaveAbsErrorScatterPlot(absErrorPlotFilePath, equation, title, zAxisLabel) absErrorHistFilePath = "static/abs_error_hist_3D.png" # simplefitter_3D title = "Absolute Error" GraphUtils.SaveDataHistogram(absErrorHistFilePath, equation.modelAbsoluteError, title) if equation.dataCache.DependentDataContainsZeroFlag != 1: perErrorPlotFilePath = "static/per_error_3D.png" # simplefitter_3D title = "Percent Error For An HTML FORM Model" GraphUtils.SavePercentErrorScatterPlot(perErrorPlotFilePath, equation, title, zAxisLabel) perErrorHistFilePath = "static/per_error_hist_3D.png" # simplefitter_3D title = "Percent Error" GraphUtils.SaveDataHistogram(perErrorHistFilePath, equation.modelPercentError, title) # generate HTML htmlToReturn = '' htmlToReturn += equation.GetDisplayName() + '<br><br>\n' htmlToReturn += equation.GetDisplayHTML() + '<br><br>\n' htmlToReturn += '<a href="' + fitStatisticsFilePath + '">Link to parameter and fit statistics</a><br><br>\n' htmlToReturn += '<a href="' + sourceCodeFilePath + '">Link to source code, all available languages</a><br><br>\n' htmlToReturn += '<img src="' + graphFilePath_Surface + '"><br><br>\n' htmlToReturn += '<img src="' + graphFilePath_Contour + '"><br><br>\n' htmlToReturn += '<img src="' + absErrorPlotFilePath + '"><br><br>\n' htmlToReturn += '<img src="' + absErrorHistFilePath + '"><br><br>\n' if equation.dataCache.DependentDataContainsZeroFlag != 1: htmlToReturn += '<img src="' + perErrorPlotFilePath + '"><br><br>\n' htmlToReturn += '<img src="' + perErrorHistFilePath + '"><br><br>\n' return '<html><body>' + htmlToReturn + '</body></html>'
def test_CalculateCoefficientAndFitStatisticsUsingUserDefinedFunction_2D( self): model_df_e_ShouldBe = 9.0 model_df_r_ShouldBe = 1.0 model_r2_ShouldBe = 0.996389372503 model_rmse_ShouldBe = 00.142649386595 model_r2adj_ShouldBe = 0.99598819167 model_Fstat_ShouldBe = 2483.64151657 model_Fpv_ShouldBe = 2.64577248998e-12 model_ll_ShouldBe = 5.81269665017 model_aic_ShouldBe = -0.693217572758 model_bic_ShouldBe = -0.620872977703 model_cov_beta_ShouldBe = numpy.array([[1.93842855, -0.26398964], [-0.26398964, 0.03772113]]) model_sd_beta_ShouldBe = numpy.array([0.0482103, 0.00093816]) model_tstat_beta_ShouldBe = numpy.array([-36.52226166, 49.83614545]) model_pstat_beta_ShouldBe = numpy.array( [4.28455049e-11, 2.64588351e-12]) model_ci_ShouldBe = numpy.array( [[-8.5158339321793157, -7.5224373409719512], [1.4571589560702567, 1.595735631605572]]) model = pyeq3.Models_2D.UserDefinedFunction.UserDefinedFunction( 'SSQABS', 'Default', 'm*X + b') pyeq3.dataConvertorService().ConvertAndSortColumnarASCII( model.exampleData, model, False) model.Solve() model.CalculateModelErrors(model.solvedCoefficients, model.dataCache.allDataCacheDictionary) model.CalculateCoefficientAndFitStatistics() self.assertTrue( numpy.allclose(model.df_e, model_df_e_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.df_r, model_df_r_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.r2, model_r2_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.rmse, model_rmse_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.r2adj, model_r2adj_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.Fstat, model_Fstat_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.Fpv, model_Fpv_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.ll, model_ll_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.aic, model_aic_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.bic, model_bic_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.cov_beta, model_cov_beta_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.sd_beta, model_sd_beta_ShouldBe, rtol=1.0E-05, atol=1.0E-300)) # extra tolerance self.assertTrue( numpy.allclose(model.tstat_beta, model_tstat_beta_ShouldBe, rtol=1.0E-06, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.pstat_beta, model_pstat_beta_ShouldBe, rtol=1.0E-04, atol=1.0E-300)) self.assertTrue( numpy.allclose(model.ci, model_ci_ShouldBe, rtol=1.0E-06, atol=1.0E-300))