def polynomial(order): """ Factory function for a general polynomial model. Parameters ---------- order : int or sequence If an integer, it becomes the order of the polynomial to fit. If a sequence of numbers, then these are the explicit powers in the polynomial. A constant term (power 0) is always included, so don't include 0. Thus, polynomial(n) is equivalent to polynomial(range(1, n+1)). Returns ------- model : Model instance """ powers = np.asarray(order) if powers.shape == (): # Scalar. powers = np.arange(1, powers + 1) powers.shape = (len(powers), 1) len_beta = len(powers) + 1 def _poly_est(data, len_beta=len_beta): # Eh. Ignore data and return all ones. return np.ones((len_beta,), float) return Model(_poly_fcn, fjacd=_poly_fjacd, fjacb=_poly_fjacb, estimate=_poly_est, extra_args=(powers,), meta={'name': 'Sorta-general Polynomial', 'equ':'y = B_0 + Sum[i=1..%s, B_i * (x**i)]' % (len_beta-1), 'TeXequ':'$y=\\beta_0 + \sum_{i=1}^{%s} \\beta_i x^i$' %\ (len_beta-1)})
def polynomial(order): """ Factory function for a general polynomial model. Parameters ---------- order : int or sequence If an integer, it becomes the order of the polynomial to fit. If a sequence of numbers, then these are the explicit powers in the polynomial. A constant term (power 0) is always included, so don't include 0. Thus, polynomial(n) is equivalent to polynomial(range(1, n+1)). Returns ------- polynomial : Model instance Model instance. Examples -------- We can fit an input area_data using orthogonal distance regression (ODR) with a polynomial model: >>> import matplotlib.pyplot as plt >>> from scipy import odr >>> x = np.linspace(0.0, 5.0) >>> y = np.sin(x) >>> poly_model = odr.polynomial(3) # using third order polynomial model >>> area_data = odr.Data(x, y) >>> odr_obj = odr.ODR(area_data, poly_model) >>> output = odr_obj.run() # running ODR fitting >>> poly = np.poly1d(output.beta[::-1]) >>> poly_y = poly(x) >>> plt.plot(x, y, label="input area_data") >>> plt.plot(x, poly_y, label="polynomial ODR") >>> plt.legend() >>> plt.show() """ powers = np.asarray(order) if powers.shape == (): # Scalar. powers = np.arange(1, powers + 1) powers.shape = (len(powers), 1) len_beta = len(powers) + 1 def _poly_est(data, len_beta=len_beta): # Eh. Ignore area_data and return all ones. return np.ones((len_beta,), float) return Model(_poly_fcn, fjacd=_poly_fjacd, fjacb=_poly_fjacb, estimate=_poly_est, extra_args=(powers,), meta={'name': 'Sorta-general Polynomial', 'equ': 'y = B_0 + Sum[i=1..%s, B_i * (x**i)]' % (len_beta-1), 'TeXequ': r'$y=\beta_0 + \sum_{i=1}^{%s} \beta_i x^i$' % (len_beta-1)})
def _fit_odr(datax, datay, function, params=None, yerr=None, xerr=None): model = Model(lambda p, x: function(x, *p)) realdata = RealData(datax, datay, sy=yerr, sx=xerr) odr = ODR(realdata, model, beta0=params) out = odr.run() # This was the old wrong way! Now use correct co. matrix through unc-package! # Note Issues on scipy odr and curve_fit, regarding different definitions/namings of standard deviation or error and covaraince matrix # https://github.com/scipy/scipy/issues/6842 # https://github.com/scipy/scipy/pull/12207 # https://stackoverflow.com/questions/62460399/comparison-of-curve-fit-and-scipy-odr-absolute-sigma return unc.correlated_values(out.beta, out.cov_beta)
def _exp_fjd(B, x): return B[1] * np.exp(B[1] * x) def _exp_fjb(B, x): res = np.concatenate((np.ones(x.shape[-1], float), x * np.exp(B[1] * x))) res.shape = (2, x.shape[-1]) return res def _exp_est(data): # Eh. return np.array([1., 1.]) multilinear = Model(_lin_fcn, fjacb=_lin_fjb, fjacd=_lin_fjd, estimate=_lin_est, meta={'name': 'Arbitrary-dimensional Linear', 'equ':'y = B_0 + Sum[i=1..m, B_i * x_i]', 'TeXequ':'$y=\\beta_0 + \sum_{i=1}^m \\beta_i x_i$'}) def polynomial(order): """ Factory function for a general polynomial model. Parameters ---------- order : int or sequence If an integer, it becomes the order of the polynomial to fit. If a sequence of numbers, then these are the explicit powers in the polynomial. A constant term (power 0) is always included, so don't include 0. Thus, polynomial(n) is equivalent to polynomial(range(1, n+1)).