def lorentzian_fitter(subset_freq, subset_psd_q, max_iters=50, rtol=1e-8, verbose=False): """ fits subset_psd_q to the functional form A / ( (subset_freq - fo)**2 + Y**2 ) attemps to fit at most max_iters times declares success if converged to within rtol assumes subset_freq, subset_psd_q are already sorted """ # find a starting guess for the peak f_p = zip(subset_freq, subset_psd_q) f_p.sort(key=lambda l: l[1], reverse=True) f_p, psd_peak = f_p[0] subset = np.array( [np.array(subset_freq), np.array(subset_psd_q)] ) n = len(subset[0]) # number of data points p = 3 # number of fitting parameters mysys = pygsl_mfN.gsl_multifit_function_fdf(lorentzian_fit, lorentzian_dfit, lorentzian_fitdfit, subset, n, p) solver = pygsl_mfN.lmsder(mysys, n, p) fit_params_guess = (f_p, 1e-5, psd_peak) # guess for starting point: fo, Y, A solver.set(fit_params_guess) if verbose: print "# %5s %9s %9s %9s %10s" % ("iter", "fo", "Y", "A", "|f(x)|") for iter in range(1,max_iters+1): # iterate solver status = solver.iterate() # move fit parameters _fit_params = solver.getx() # new guess for fit params dfit_params = solver.getdx() # change in fit params fits = np.array(solver.getf()) # residuals at every data point between data and fit J = solver.getJ() # jacobian of the fit? tdx = pygsl_mfN.gradient(J, fits) # gradient of the fit? status = pygsl_mfN.test_delta(dfit_params, _fit_params, rtol, rtol) fn = np.sum(fits*fits)**0.5 # sum of squares of the residual if status == pygsl_errno.GSL_SUCCESS: if verbose: print "# Convereged :" break if verbose: print " %5d % .7f % .7f % .7f % .7f" %(iter, _fit_params[0], _fit_params[1], _fit_params[2], fn) # report state else: if verbose: print "WARNING! Number of Iterations exceeded in nmode_state.lorentzian_fitter!" print "\tmodeNo=%d , peak_freq=%f, peak_psd=%f" % (m, f_p, psd_peak) print "continuing with best guess after %d iterations" % max_iters # get error bars on the fit parameters # J = solver.getJ() # not needed? covar = pygsl_mfN.covar(solver.getJ(), 0.0) # covarience matrix if verbose: print "# fo = % .5f +/- % .5f" % (_fit_params[0], covar[0,0]) print "# Y = % .5f +/- % .5f" % (_fit_params[1], covar[1,1]) print "# A = % .5f +/- % .5f" % (_fit_params[2], covar[2,2]) return _fit_params, [covar[0][0], covar[1][1], covar[2][2]]
def run_fdfsolver(): A = 1. lambda_ = .1 b = .5 n = 40 p = 3 t = numx.arange(n); y = testfunc(t, A, lambda_, b) sigma = numx.ones(n) * 0.1 data = numx.array((t,y,sigma),) mysys = multifit_nlin.gsl_multifit_function_fdf(exp_f, exp_df, exp_fdf, data, n,p) solver = multifit_nlin.lmsder(mysys, n, p) #solver = multifit_nlin.lmder(mysys, n, p) x = numx.array((1.0, 0.0, 0.0)) solver.set(x) print "# Testing solver ", solver.name() print "# %5s %9s %9s %9s %10s" % ("iter", "A", "lambda", "b", "|f(x)|") for iter in range(20): status = solver.iterate() x = solver.getx() dx = solver.getdx() f = solver.getf() J = solver.getJ() tdx = multifit_nlin.gradient(J, f) status = multifit_nlin.test_delta(dx, x, 1e-8, 1e-8) fn = numx.sqrt(numx.sum(f*f)) if status == errno.GSL_SUCCESS: print "# Convereged :" if status == errno.GSL_SUCCESS: break print " %5d % .7f % .7f % .7f % .7f" %(iter, x[0], x[1], x[2], fn) else: raise ValueError, "Number of Iterations exceeded!" J = solver.getJ() covar = multifit_nlin.covar(solver.getJ(), 0.0) print "# A = % .5f +/- % .5f" % (x[0], covar[0,0]) print "# lambda = % .5f +/- % .5f" % (x[1], covar[1,1]) print "# b = % .5f +/- % .5f" % (x[2], covar[2,2])
def _run(self, solver): #x = Numeric.array((1.0, .4, .1)) x = Numeric.array((1.0, 0.0, 0.0)) solver.set(x) #g.title('Start') #g.plot(Gnuplot.Data(self.data[0], self.data[1]), # Gnuplot.Data(self.data[0], testfunc(self.data[0]), # with = 'line'), # ) #raw_input() #print "Testing solver ", solver.name() #print "%5s %9s %9s %9s %10s" % ("iter", "A", "lambda", "b", "|f(x)|") for iter in range(20): status = solver.iterate() assert (status == 0 or status == -2) x = solver.getx() dx = solver.getdx() f = solver.getf() J = solver.getJ() tdx = multifit_nlin.gradient(J, f) status = multifit_nlin.test_delta(dx, x, 1e-8, 1e-8) #status = multifit_nlin.test_gradient(dx, 1e-4) fn = Numeric.sqrt(Numeric.sum(f * f)) #g.title('Iteration') if status == 0: break #print "%5d % .7f % .7f % .7f % .7f" %(iter, x[0], x[1], x[2], fn) #g.plot(Gnuplot.Data(self.data[0], self.data[1]), # Gnuplot.Data(self.data[0], # testfunc(self.data[0], x[0], x[1], x[2]), # with = 'line', title='iteration ' + str(iter)), # ) #raw_input() else: raise ValueError, "Number of Iterations exceeded!" #print "Convereged :" #print "%5d % .7f % .7f %.7f % .7f" %(iter, x[0], x[1], x[2], fn) assert (Numeric.absolute(x[0] - self.A) < _eps) assert (Numeric.absolute(x[1] - self.lambda_) < _eps) assert (Numeric.absolute(x[2] - self.b) < _eps) #J = solver.getJ() #print "shape = ", J.shape covar = multifit_nlin.covar(solver.getJ(), 0.0)
def run_fdfsolver(): A = 1. lambda_ = .1 b = .5 n = 40 p = 3 t = numx.arange(n) y = testfunc(t, A, lambda_, b) sigma = numx.ones(n) * 0.1 data = numx.array((t, y, sigma), ) mysys = multifit_nlin.gsl_multifit_function_fdf(exp_f, exp_df, exp_fdf, data, n, p) solver = multifit_nlin.lmsder(mysys, n, p) #solver = multifit_nlin.lmder(mysys, n, p) x = numx.array((1.0, 0.0, 0.0)) solver.set(x) print("# Testing solver ", solver.name()) print("# %5s %9s %9s %9s %10s" % ("iter", "A", "lambda", "b", "|f(x)|")) for iter in range(20): status = solver.iterate() x = solver.getx() dx = solver.getdx() f = solver.getf() J = solver.getJ() tdx = multifit_nlin.gradient(J, f) status = multifit_nlin.test_delta(dx, x, 1e-8, 1e-8) fn = numx.sqrt(numx.sum(f * f)) if status == errno.GSL_SUCCESS: print("# Convereged :") if status == errno.GSL_SUCCESS: break print(" %5d % .7f % .7f % .7f % .7f" % (iter, x[0], x[1], x[2], fn)) else: raise ValueError("Number of Iterations exceeded!") J = solver.getJ() covar = multifit_nlin.covar(solver.getJ(), 0.0) print("# A = % .5f +/- % .5f" % (x[0], covar[0, 0])) print("# lambda = % .5f +/- % .5f" % (x[1], covar[1, 1])) print("# b = % .5f +/- % .5f" % (x[2], covar[2, 2]))
def _run(self, solver): #x = Numeric.array((1.0, .4, .1)) x = Numeric.array((1.0, 0.0, 0.0)) solver.set(x) #g.title('Start') #g.plot(Gnuplot.Data(self.data[0], self.data[1]), # Gnuplot.Data(self.data[0], testfunc(self.data[0]), # with = 'line'), # ) #raw_input() #print "Testing solver ", solver.name() #print "%5s %9s %9s %9s %10s" % ("iter", "A", "lambda", "b", "|f(x)|") for iter in range(20): status = solver.iterate() assert(status == 0 or status == -2) x = solver.getx() dx = solver.getdx() f = solver.getf() J = solver.getJ() tdx = multifit_nlin.gradient(J, f) status = multifit_nlin.test_delta(dx, x, 1e-8, 1e-8) #status = multifit_nlin.test_gradient(dx, 1e-4) fn = Numeric.sqrt(Numeric.sum(f*f)) #g.title('Iteration') if status == 0: break #print "%5d % .7f % .7f % .7f % .7f" %(iter, x[0], x[1], x[2], fn) #g.plot(Gnuplot.Data(self.data[0], self.data[1]), # Gnuplot.Data(self.data[0], # testfunc(self.data[0], x[0], x[1], x[2]), # with = 'line', title='iteration ' + str(iter)), # ) #raw_input() else: raise ValueError, "Number of Iterations exceeded!" #print "Convereged :" #print "%5d % .7f % .7f %.7f % .7f" %(iter, x[0], x[1], x[2], fn) assert(Numeric.absolute(x[0] - self.A) < _eps) assert(Numeric.absolute(x[1] - self.lambda_) < _eps) assert(Numeric.absolute(x[2] - self.b) < _eps) #J = solver.getJ() #print "shape = ", J.shape covar = multifit_nlin.covar(solver.getJ(), 0.0)
def _run(self, solver): x = Numeric.array((1.0, 0.0, 0.0)) solver.set(x) for iter in range(20): status = solver.iterate() assert (status == 0 or status == -2) x = solver.getx() dx = solver.getdx() f = solver.getf() J = solver.getJ() tdx = multifit_nlin.gradient(J, f) status = multifit_nlin.test_delta(dx, x, 1e-8, 1e-8) fn = Numeric.sqrt(Numeric.sum(f * f)) if status == 0: break else: raise ValueError("Number of Iterations exceeded!") assert (Numeric.absolute(x[0] - self.A) < _eps) assert (Numeric.absolute(x[1] - self.lambda_) < _eps) assert (Numeric.absolute(x[2] - self.b) < _eps) covar = multifit_nlin.covar(solver.getJ(), 0.0)
def __fit_peaks_lorentzian(freq, fft_q, max_iters=50, delta=0, verbose=False, rtol=1e-8): """ fits a lorentzian to each peak of the PSD of q currently, we naively find peaks by searching for local maxima the fitting-subset of data is selected by using half the data between the peak and the nearest local minimum --> THIS MAY BE FRAGILE assumes freq, fft_q are sorted in order of increasing frequency """ psd_q = [ [ Q[0]**2 + Q[1]**2 for Q in fft_q[m]] for m in range(len(fft_q))] fit_params = [] fit_params_covar = [] for m in range(len(psd_q)): # iterate through for each mode peaks, min_peaks = nm_u.peakdet(psd_q[m], x=freq, delta=delta, n_lowpass=n_lowpass) # find peaks/minima peaks.sort(key=lambda line: line[0]) # sort peaks by their frequencies min_peaks.sort(key=lambda line: line[0]) min_peaks.insert(0, (freq[0], psd_q[0])) # add end points to min_peaks for data subset determination) min_peaks.append((freq[-1], psd_q[-1])) mfit_params = [] # store the best-fit parameters mfit_params_covar = [] # set up fitting data set surrounding each peak min_freq = min(freq) max_freq = max(freq) min_peaks_ind = 0 freq_min_ind = 0 freq_max_ind = 0 for peak in peaks: f_p , psd_peak = peak # print " f*P=%f, PSD=%f" % (peak) while min_peaks[min_peaks_ind][0] < f_p: # find the nearest local minima to f_p min_freq = min_peaks[min_peaks_ind][0] min_peaks_ind += 1 freq_min = max(min(f_p-bw, 0.5*(min_freq + f_p)), freq[0]) freq_max = min(max(f_p+bw, 0.5*(f_p + min_peaks[min_peaks_ind][0])), freq[-1]) print f_p-bw, freq_min, f_p, freq_max, f_p+bw subset_freq = [] subset_psd_q = [] while freq[freq_min_ind] < freq_min: # locate the proper subset of data freq_min_ind += 1 freq_max_ind = freq_min_ind while (freq[freq_max_ind] < freq_max) and (freq_max_ind < len(freq)): subset_freq.append(freq[freq_max_ind]) # add points to the subset subset_psd_q.append(psd_q[m][freq_max_ind]) freq_max_ind += 1 freq_min_ind = freq_max_ind # start off at this point for the next peak if len(subset_freq) <= 3: if verbose: print "WARNING: not enough data surrounding this subset. Likely to see an error, so we skip this peak." continue subset = np.array( [np.array(subset_freq), np.array(subset_psd_q)] ) n = len(subset[0]) # number of data points p = 3 # number of fitting parameters mysys = pygsl_mfN.gsl_multifit_function_fdf(lorentzian_fit, lorentzian_dfit, lorentzian_fitdfit, subset, n, p) solver = pygsl_mfN.lmsder(mysys, n, p) fit_params_guess = (f_p, 1e-5, psd_peak) # guess for starting point: fo, Y, A solver.set(fit_params_guess) if verbose: print "# %5s %9s %9s %9s %10s" % ("iter", "fo", "Y", "A", "|f(x)|") for iter in range(1,max_iters+1): # iterate solver status = solver.iterate() # move fit parameters _fit_params = solver.getx() # new guess for fit params dfit_params = solver.getdx() # change in fit params fits = np.array(solver.getf()) # residuals at every data point between data and fit J = solver.getJ() # jacobian of the fit? tdx = pygsl_mfN.gradient(J, fits) # gradient of the fit? status = pygsl_mfN.test_delta(dfit_params, _fit_params, rtol, rtol) fn = np.sum(fits*fits)**0.5 # sum of squares of the residual if status == pygsl_errno.GSL_SUCCESS: if verbose: print "# Convereged :" break if verbose: print " %5d % .7f % .7f % .7f % .7f" %(iter, _fit_params[0], _fit_params[1], _fit_params[2], fn) # report state else: if verbose: print "WARNING! Number of Iterations exceeded in nmode_state.fit_peaks_lorentzian!" print "\tmodeNo=%d , peak_freq=%f, peak_psd=%f" % (m, f_p, psd_peak) print "continuing with best guess after %d iterations" % max_iters # get error bars on the fit parameters # J = solver.getJ() # not needed? covar = pygsl_mfN.covar(solver.getJ(), 0.0) # covarience matrix if verbose: print "# fo = % .5f +/- % .5f" % (_fit_params[0], covar[0,0]) print "# Y = % .5f +/- % .5f" % (_fit_params[1], covar[1,1]) print "# A = % .5f +/- % .5f" % (_fit_params[2], covar[2,2]) mfit_params.append(_fit_params) mfit_params_covar.append([covar[0][0], covar[1][1], covar[2][2]]) fit_params.append(mfit_params) fit_params_covar.append(mfit_params_covar) return fit_params, fit_params_covar
def broken_PowLaw_fitter(x, y, sigma, max_iters=50, rtol=1e-8, verbose=False): """ fits the data with y = A * x**(-alpha) * ((1 + exp(x/beta))/2)**(-gamma) attempting no more than "max_iters" times to converge return _fit_params, [covar[i][i] for i in range(len(covar))], red_chi2 """ x = np.array(x) y = np.array(y) n = len(x) # number of data points p = 4 # number of fitting parameters ### set up system mysys = pygsl_mfN.gsl_multifit_function_fdf( broken_PowLaw_fit, broken_PowLaw_dfit, broken_PowLaw_fitdfit, np.array( [x, y, sigma] ), n, p) solver = pygsl_mfN.lmsder(mysys, n, p) ### find starting point for parameters alpha = 0.75 beta = len(x)*0.8 gamma = beta/20 A = y[0] * 0.8 fit_params_guess = [A, alpha, beta, gamma] # guess for fit parameters solver.set(fit_params_guess) if verbose: print "# %5s %9s %9s %9s %9s %10s" % ("iter", "A", "alpha", "beta", "gamma", "|f(x)|") print " %5d % .7f % .7f % .7f %.7f" % tuple( [0]+fit_params_guess ) # report initial guess for iter in range(1,max_iters+1): status = solver.iterate() # move fit params _fit_params = solver.getx() # new guess dfit_params = solver.getdx() # change in fit params fits = np.array( solver.getf() ) # residuals at every data point J = solver.getJ() # jacobian of fit tdx = pygsl_mfN.gradient( J, fits ) # gradient at fit status = pygsl_mfN.test_delta(dfit_params, _fit_params, rtol, rtol) # just copied, not understood... fn = np.sum((fits/sigma)**2)**0.5 # sum square errors if status == pygsl_errno.GSL_SUCCESS: if verbose: print "# Converged :" break if verbose: print " %5d % .7f % .7f % .7f % .7f % .7f" % tuple([iter] + list(_fit_params) + [fn]) # report state else: if verbose: print "WARNING! Number of Iterations exceeded in nmode_state.broken_PowLaw_fitter!" print "continuing with best guess after %d iterations" % max_iters # get error bars on fit params covar = pygsl_mfN.covar(solver.getJ(), 0.0) # covariance matrix red_chi2 = 1.0*sum( (broken_PowLaw(x, _fit_params) - y)**2 / y )/len(x) if verbose: print "# A = % .5f +/- % .5f" % (_fit_params[0], covar[0,0]) print "# alpha = % .5f +/- % .5f" % (_fit_params[1], covar[1,1]) print "# beta = % .5f +/- % .5f" % (_fit_params[2], covar[2,2]) print "# gamma = % .5f +/- % .5f" % (_fit_params[3], covar[3,3]) print "# red_chi2 = % .6f" % red_chi2 return _fit_params, [covar[i][i] for i in range(len(covar))], red_chi2
def steps_fitter(x, y, sigma, n, max_iters=50, rtol=1e-8, verbose=False): """ fits data to "steps" with n terms """ if not isinstance(x, np.ndarray): x = np.array( x ) if not isinstance(y, np.ndarray): y = np.array( y ) if not isinstance(sigma, np.ndarray): sigma = np.array( sigma ) n_pts = len(x) ### number of points p = 3*n ### number of fitting parameters ### set up system if verbose: print "setting up objects" mysys = pygsl_mfN.gsl_multifit_function_fdf( steps_fit, steps_dfit, steps_fitdfit, np.array( [x, y, sigma] ), n_pts, p) solver = pygsl_mfN.lmsder(mysys, n_pts, p) ### starting points if verbose: print "setting up stating point" params = [] for i in xrange(n): a = -8.2 b = 2.6e-6 C = y[0]/x[0]**a # C = np.mean(y)/np.mean(x)**a params += [ C, a, b] solver.set(params) ### set starting point if verbose: s = "# %5s" S = " %5d"%0 for i in xrange(n): s += " %9s %9s %9s"%("C", "a", "b") S += " %.7f %.7f %7f"%tuple(params[3*i:3*(i+1)]) print s print S for iter in range(1,max_iters+1): status = solver.iterate() # move fit params _fit_params = solver.getx() # new guess dfit_params = solver.getdx() # change in fit params fits = np.array( solver.getf() ) # residuals at every data point J = solver.getJ() # jacobian of fit tdx = pygsl_mfN.gradient( J, fits ) # gradient at fit status = pygsl_mfN.test_delta(dfit_params, _fit_params, rtol, rtol) # just copied, not understood... fn = np.sum((fits)**2)**0.5 # sum square errors if status == pygsl_errno.GSL_SUCCESS: if verbose: print "# Converged :" break if verbose: S = " %5d"%iter for i in xrange(n): S += " %.7f %.7f %7f"%tuple(_fit_params[3*i:3*(i+1)]) S += " %.7f"%fn print S else: if verbose: print "WARNING! Number of Iterations exceeded in nmode_state.broken_PowLaw_fitter!" print "continuing with best guess after %d iterations" % max_iters # get error bars on fit params covar = pygsl_mfN.covar(solver.getJ(), 0.0) # covariance matrix red_chi2 = 1.0*sum( (steps(x, _fit_params) - y)**2 / y )/len(x) if verbose: s = "#" S = " " ss= " " for i in xrange(n): s += " %9s %9s %9s"%("C", "a", "b") S += " %.7f %.7f %7f"%tuple(_fit_params[3*i:3*(i+1)]) ss+= " %.7f %.7f %7f"%tuple(covar[i][i] for i in xrange(3*i, 3*(i+1))) print s print S return _fit_params, [covar[i][i] for i in range(len(covar))], red_chi2