Guest User

Untitled

a guest
Oct 18th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.99 KB | None | 0 0
  1. import numpy as np
  2. from scipy.optimize import minimize
  3.  
  4. class GeneralizedLeastSquares:
  5. """
  6. This class is used to compute the parameters (m,b) that produce
  7. the best-fitting line through a set of (x,y) points. Here, (m,b)
  8. refer to the slope and y-intercept of y = mx + b.
  9. (Eventually, this will be a generalized routine.)
  10. """
  11.  
  12. def __init__(self, x=None, y=None, parameters=[], weights=None, method='minimize residuals', minimization='Nelder-Mead'):
  13. self.x = x
  14. self.y = y
  15. self.parameters = parameters
  16. self.weights = weights
  17. self.method = method
  18. self.minimization = minimization
  19.  
  20. def __str__(self, parameters):
  21. print("nslope = %.2f ny-intercept = %.2f n" %(self.parameters[0], self.parameters[1]))
  22.  
  23. @classmethod
  24. def get_fitting_func(self):
  25. """ This function returns y_new = mx + b """
  26. return [self.parameters[0] * self.x[idx] + self.parameters[1] for idx in range(len(self.x))]
  27.  
  28. @classmethod
  29. def get_residuals(self):
  30. """ This function returns the residuals """
  31. y_trial = get_fitting_func(self)
  32. return [(self.y[idx] - y_trial[idx])**2 for idx in range(len(self.y)) if len(self.y) == len(y_trial)]
  33.  
  34. @classmethod
  35. def update_weights(self):
  36. """ This function returns the weights to be used """
  37. if self.weights is None:
  38. res = np.ones(len(self.x))
  39. else:
  40. resid = get_residuals(self)
  41. inv_resid = [abs(1 / resid[idx]) for idx in range(len(resid))]
  42. tot_resid = sum(inv_resid)
  43. res = [inv_resid[idx] / tot_resid for idx in range(len(inv_resid))]
  44. return res
  45.  
  46. @classmethod
  47. def get_error_func(self):
  48. """ This function returns the sum of the weighted inverse residuals """
  49. resid = get_residuals(self)
  50. return sum([weights[idx] * resid[idx] for idx in range(len(resid)) if len(resid) == len(weights)])
  51.  
  52. @classmethod
  53. def perform_gls_fit(self):
  54. """ This function returns the fitting parameters of the linear fit """
  55. if self.parameters == 'estimate':
  56. slope_est = (self.y[-1] - self.y[0]) / (self.x[-1] - self.x[0])
  57. y_int_est = np.mean([self.y[-1] - slope_est * self.x[-1], self.y[0] - slop_est * self.x[0]])
  58. self.parameters = [slope_est, y_int_est]
  59. elif not isinstance(self.parameters, (list, np.ndarray)):
  60. raise ValueError("parameters = 'estimate' or [slope, y-intercept]")
  61. if self.method == 'minimize residuals':
  62. res = minimize(get_error_func, x0=self.parameters, args=(self,), method=self.minimization)
  63. self.parameters = res.x
  64. return self.parameters
  65.  
  66. # y = 2x+3
  67. x_data = np.linspace(1, 10, 10)
  68. y_data = np.array([5, 7.1, 9.2, 10.8, 12.9, 15.1, 17, 19.2, 20.8, 23])
  69. gg = GeneralizedLeastSquares(x_data, y_data, 'estimate').perform_gls_fit
  70. print(gg)
  71.  
  72. ## produces this output
  73. <bound method GeneralizedLeastSquares.perform_gls_fit of <class '__main__.GeneralizedLeastSquares'>>
Add Comment
Please, Sign In to add comment