def test_get_completeness_points(self): ''' Tests the function get_completeness_points using a synthetic set of "sigma" derived from a bilinear function with known gradients and crossover points ''' crossovers = [20., 50., 80.] params1 = [-0.5, -1.0, np.log10(crossovers[0]), 1.5] params2 = [-0.5, -1.3, np.log10(crossovers[1]), 1.0] params3 = [-0.5, -0.8, np.log10(crossovers[2]), 0.7] n_years = np.hstack([1., 5., np.arange(10., 110., 10.)]) number_values = len(n_years) yvals_1 = np.zeros(number_values, dtype=float) yvals_2 = np.zeros(number_values, dtype=float) yvals_3 = np.zeros(number_values, dtype=float) for ival in range(0, number_values): yvals_1[ival] = 10.**piecewise_linear_scalar( params1, np.log10(n_years[ival])) yvals_2[ival] = 10.**piecewise_linear_scalar( params2, np.log10(n_years[ival])) yvals_3[ival] = 10.**piecewise_linear_scalar( params3, np.log10(n_years[ival])) test_sigma = np.column_stack([yvals_1, yvals_2, yvals_3]) (ntime, nmags) = np.shape(test_sigma) completeness_time, gradients, _ = \ self.process.get_completeness_points(n_years, test_sigma, nmags, ntime) self.assertTrue(fabs(completeness_time[0] - crossovers[0]) < 1.0) self.assertTrue(fabs(completeness_time[1] - crossovers[1]) < 1.0) self.assertTrue(fabs(completeness_time[2] - crossovers[2]) < 1.0) self.assertTrue(fabs(gradients[0] - -1.0) < 0.1) self.assertTrue(fabs(gradients[1] - -1.3) < 0.1) self.assertTrue(fabs(gradients[2] - -0.8) < 0.1)
def test_get_completeness_points(self): ''' Tests the function get_completeness_points using a synthetic set of "sigma" derived from a bilinear function with known gradients and crossover points ''' crossovers = [20., 50., 80.] params1 = [-0.5, -1.0, np.log10(crossovers[0]), 1.5] params2 = [-0.5, -1.3, np.log10(crossovers[1]), 1.0] params3 = [-0.5, -0.8, np.log10(crossovers[2]), 0.7] n_years = np.hstack([1., 5., np.arange(10., 110., 10.)]) number_values = len(n_years) yvals_1 = np.zeros(number_values, dtype=float) yvals_2 = np.zeros(number_values, dtype=float) yvals_3 = np.zeros(number_values, dtype=float) for ival in range(0, number_values): yvals_1[ival] = 10. ** piecewise_linear_scalar(params1, np.log10(n_years[ival])) yvals_2[ival] = 10. ** piecewise_linear_scalar(params2, np.log10(n_years[ival])) yvals_3[ival] = 10. ** piecewise_linear_scalar(params3, np.log10(n_years[ival])) test_sigma = np.column_stack([yvals_1, yvals_2, yvals_3]) (ntime, nmags) = np.shape(test_sigma) completeness_time, gradients, _ = \ self.process.get_completeness_points(n_years, test_sigma, nmags, ntime) self.assertTrue(fabs(completeness_time[0] - crossovers[0]) < 1.0) self.assertTrue(fabs(completeness_time[1] - crossovers[1]) < 1.0) self.assertTrue(fabs(completeness_time[2] - crossovers[2]) < 1.0) self.assertTrue(fabs(gradients[0] - -1.0) < 0.1) self.assertTrue(fabs(gradients[1] - -1.3) < 0.1) self.assertTrue(fabs(gradients[2] - -0.8) < 0.1)
def get_bilinear_residuals_stepp(input_params, xvals, yvals, slope1_fit): ''' Returns the residual sum-of-squares value of a bilinear fit to a data set - with a segment - 1 gradient fixed by an input value (slope_1_fit) :param list input_params: Input parameters for the bilinear model [slope2, crossover_point, intercept] :param numpy.ndarray xvals: x-values of the data to be fit :param numpy.ndarray yvals: y-values of the data to be fit :param float slope1_fit: Gradient of the first slope :returns: Residual sum-of-squares of fit ''' params = np.hstack([slope1_fit, input_params]) num_x = len(xvals) y_model = np.zeros(num_x, dtype=float) residuals = np.zeros(num_x, dtype=float) for iloc in range(0, num_x): y_model[iloc] = piecewise_linear_scalar(params, xvals[iloc]) residuals[iloc] = (yvals[iloc] - y_model[iloc]) ** 2.0 return np.sum(residuals)
def setUp(self): self.xdata = np.arange(0., 11., 1.) self.params = [2.0, -1.0, 5.0, 1.0] self.ydata = np.zeros(11, dtype=float) for ival in range(0, 11): self.ydata[ival] = piecewise_linear_scalar(self.params, self.xdata[ival])
def test_fit_bilinear_function(self): ''' Tests the function to fit a bilinear model to a data set with a known set of coefficients ''' self.xdata = np.arange(0., 21., 1.) self.params = [-0.5, -1.0, 8.0, 10.0] self.ydata = np.zeros(len(self.xdata), dtype=float) for ival in range(0, len(self.xdata)): self.ydata[ival] = piecewise_linear_scalar(self.params, self.xdata[ival]) # Run analysis comp_time, gradient, model_line = self.process._fit_bilinear_to_stepp( self.xdata, self.ydata, initial_values = [-0.75, 10.0, 0.0]) # Number of decimal places lowered to allow for uncertainty in # optimisation results self.assertAlmostEqual(np.log10(comp_time), np.log10(100000219.8145678), places=3) self.assertAlmostEqual(gradient, -1.000, places=3) expected_model_line = 10.0 ** (-0.5 * self.xdata + 10.) for ival in range(0, len(model_line)): self.assertAlmostEqual(np.log10(model_line[ival]), np.log10(expected_model_line[ival]), places=3)
def get_bilinear_residuals_stepp(input_params, xvals, yvals, slope1_fit): ''' Returns the residual sum-of-squares value of a bilinear fit to a data set - with a segment - 1 gradient fixed by an input value (slope_1_fit) :param list input_params: Input parameters for the bilinear model [slope2, crossover_point, intercept] :param numpy.ndarray xvals: x-values of the data to be fit :param numpy.ndarray yvals: y-values of the data to be fit :param float slope1_fit: Gradient of the first slope :returns: Residual sum-of-squares of fit ''' params = np.hstack([slope1_fit, input_params]) num_x = len(xvals) y_model = np.zeros(num_x, dtype=float) residuals = np.zeros(num_x, dtype=float) for iloc in range(0, num_x): y_model[iloc] = piecewise_linear_scalar(params, xvals[iloc]) residuals[iloc] = (yvals[iloc] - y_model[iloc])**2.0 return np.sum(residuals)
def test_fit_bilinear_function(self): ''' Tests the function to fit a bilinear model to a data set with a known set of coefficients ''' self.xdata = np.arange(0., 21., 1.) self.params = [-0.5, -1.0, 8.0, 10.0] self.ydata = np.zeros(len(self.xdata), dtype=float) for ival in range(0, len(self.xdata)): self.ydata[ival] = piecewise_linear_scalar(self.params, self.xdata[ival]) # Run analysis comp_time, gradient, model_line = self.process._fit_bilinear_to_stepp( self.xdata, self.ydata, initial_values=[-0.75, 10.0, 0.0]) # Number of decimal places lowered to allow for uncertainty in # optimisation results self.assertAlmostEqual(np.log10(comp_time), np.log10(100000219.8145678), places=3) self.assertAlmostEqual(gradient, -1.000, places=3) expected_model_line = 10.0**(-0.5 * self.xdata + 10.) for ival in range(0, len(model_line)): self.assertAlmostEqual(np.log10(model_line[ival]), np.log10(expected_model_line[ival]), places=3)
def test_piecewise_linear_function(self): '''Test the piecewise linear calculator''' # Good parameter set - 2 segments params = [2.0, -1.0, 5.0, 0.0] values = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] expected = [0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 9.0, 8.0, 7.0, 6.0] for iloc, xval in enumerate(values): self.assertAlmostEqual(expected[iloc], utils.piecewise_linear_scalar(params, xval)) # Odd-number of values in parameters - raise value error params = [2.0, -1.0, 5.0, 0.0, 3.4] with self.assertRaises(ValueError): utils.piecewise_linear_scalar(params, 1.0) # Single segment test params1seg = [2.0, 0.0] self.assertAlmostEqual(2.0, utils.piecewise_linear_scalar(params1seg, 1.0)) # 3- segment test params = np.array([2.0, -1.0, 3.0, 4.0, 8.0, 0.0]) expected = [0.0, 2.0, 4.0, 6.0, 8.0, 7.0, 6.0, 5.0, 4.0, 7.0] for iloc, xval in enumerate(values): self.assertAlmostEqual(expected[iloc], utils.piecewise_linear_scalar(params, xval))