def f34test(data, B, fix): F = np.zeros(2, dtype=float) # pdf C = np.zeros(2, dtype=float) # p-values B3 = np.zeros(3, dtype=float) # for the 2nd order EOS, assign K0 and V0 from user guesses B3[0] = B[0] B3[1] = B[1] B3[2] = B[3] if data.EOS_type == GEOST_thermo.types().names[0]: # Figure out what EOS's to use # If birch murnaghan odr_model = odrpack.Model(fcn=GEOST_thermo.BM3_V, fjacb=GEOST_thermo.BM3_V_JACB, fjacd=GEOST_thermo.BM3_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B3, ifixb=[fix[0],fix[1],fix[3]]) odr.set_job(deriv=3) # Use user-supplied derivatives output = odr.run() # Output of ODR run ref_B3 = output.beta # LSQ best-fit parameters err_B3 = output.sd_beta # Parameter errors (1-sigma) f3 = GEOST_thermo.BM3_V(ref_B3,data.V) df3 = data.V.shape[0] - 3 odr_model = odrpack.Model(fcn=GEOST_thermo.BM4_V, fjacb=GEOST_thermo.BM4_V_JACB, fjacd=GEOST_thermo.BM4_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B, ifixb=fix) odr.set_job(deriv=3) # Use user-supplied derivatives, but CHECK THEM!!! output = odr.run() # Output of ODR run ref_B4 = output.beta # LSQ best-fit parameters err_B4 = output.sd_beta # Parameter errors (1-sigma) f4 = GEOST_thermo.BM3_V(ref_B3,data.V) df4 = data.V.shape[0] - 4 elif data.EOS_type == GEOST_thermo.types().names[1]: # If Natural strain odr_model = odrpack.Model(fcn=GEOST_thermo.NS3_V, fjacb=GEOST_thermo.NS3_V_JACB, fjacd=GEOST_thermo.NS3_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B3, ifixb=[fix[0], fix[1], fix[3]]) odr.set_job(deriv=3) # Use user-supplied derivatives, but CHECK THEM!!! output = odr.run() # Output of ODR run ref_B3 = output.beta # LSQ best-fit parameters err_B3 = output.sd_beta # Parameter errors (1-sigma) f3 = GEOST_thermo.NS3_V(ref_B3,data.V) df3 = data.V.shape[0] - 3 odr_model = odrpack.Model(fcn=GEOST_thermo.NS4_V, fjacb=GEOST_thermo.NS4_V_JACB, fjacd=GEOST_thermo.NS4_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B, ifixb=fix) odr.set_job(deriv=3) # Use user-supplied derivatives, but CHECK THEM!!! output = odr.run() # Output of ODR run ref_B4 = output.beta # LSQ best-fit parameters err_B4 = output.sd_beta # Parameter errors (1-sigma) f4 = GEOST_thermo.NS4_V(ref_B4,data.V) df4 = data.V.shape[0] - 4 elif data.EOS_type == GEOST_thermo.types().names[2]: self.LOG_PRINT("ERROR in PLOTS: Cannot do F-test using Vinet EOS.") else: self.LOG_PRINT("ERROR in PLOTS: Unrecognized value of EOS_SELECT") chisq_3 = float(0) chisq_4 = float(0) for i in range(data.P.shape[0]): # Compute the chi-squared for each EOS chisq_3 += (data.P[i] - f3[i])**2 chisq_4 += (data.P[i] - f4[i])**2 # Compute the F-statistic Fx34 = (chisq_3 - chisq_4)/(chisq_4/df4) x1 = np.linspace(0.01, 2*Fx34, 128) pdf34 = f_dist.pdf(x1, 1, df4) cdf34 = f_dist.cdf(x1, 1, df4) # Use Scipy's built-in F-distribution methods F = f_dist.pdf(Fx34, 1, df4) # Compute the P-value C = 1 - f_dist.cdf(Fx34, 1, df4) # Finally, Make the plot. SHould be a 1 row 2 column plot showing # f-test for 2nd to 3rd order EOS and 3rd to 4th order EOS. plt.figure() fig = plt.gcf() fig.canvas.set_window_title("F-Test Results") plt.plot(x1, pdf34, 'r', linewidth=3, alpha=0.8) plt.plot(x1, cdf34, 'b', linewidth=3, alpha=0.8) plt.plot(Fx34, f_dist.pdf(Fx34, 1, df4), 'ko') plt.fill_between(x1, 0, pdf34, where=f_dist.cdf(Fx34, 1, df4)<cdf34, facecolor='red', alpha=0.2) plt.xticks(fontsize=14) plt.ylim([-0.01,1.01]) plt.title("Comparing 3rd vs. 4th order EOS", fontsize=14) plt.xlabel(r"$\left( \chi^{2}_{3} - \chi^{2}_{4} \right) / \left(\chi^{2}_{4} / \nu_{4} \right)$", fontsize=12) plt.legend(['PDF', 'CDF', r"$F_{X}$"], loc='upper right', numpoints=1) plt.text(Fx34, f_dist.pdf(Fx34, 1, df4)+0.05, "p-value= {:8.4f}".format(1-f_dist.cdf(Fx34, 1, df4)), fontsize=14) plt.tight_layout() return [chisq_3/df3, chisq_4/df4, Fx34, f_dist.cdf(Fx34, 1, df4)]
def ON_REFINE_PRESS(): global data name = thermo.types().names[0] # Which EOS fix = np.zeros(4, dtype=int) # Fix flags for refinement beta = np.zeros(4, dtype=float) # Refineable param 1st guesses fix, beta = GEOST_gui.GUI().FIX_FLAG() # Assign fix flags, and parameter guesses # Sort out which EOS to work with, derivatives, etc. if name == app.EOS_names[0]: # Birch-Murnaghan if app.EOS_order.get() == 2: f = thermo.BM2_V jacb = thermo.BM2_V_JACB jacd = thermo.BM2_V_JACD elif app.EOS_order.get() == 3: f = thermo.BM3_V jacb = thermo.BM3_V_JACB jacd = thermo.BM3_V_JACD elif app.EOS_order.get() == 4: f = thermo.BM4_V jacb = thermo.BM4_V_JACB jacd = thermo.BM4_V_JACD elif name == app.EOS_names[1]: # Natural Strain if app.EOS_order.get() == 2: f = thermo.NS2_V jacb = thermo.NS2_V_JACB jacd = thermo.NS2_V_JACD elif app.EOS_order.get() == 3: f = thermo.NS3_V jacb = thermo.NS3_V_JACB jacd = thermo.NS3_V_JACD elif app.EOS_order.get() == 4: f = thermo.NS4_V jacb = thermo.NS4_V_JACB jacd = thermo.NS4_V_JACD elif name == app.EOS_names[2]: # Vinet f = thermo.VINET_V jacb = thermo.VINET_V_JACB jacd = thermo.VINET_V_JACD # ODR SETUP # model contains information about the ODR functions. # fcn = model function to refine parameters from # fjacb = derivatives of fcn w.r.t. parameters # fjacd = derivatives of fcn w.r.t. independent var. odr_model = odrpack.Model(fcn=f, fjacb=jacb, fjacd=jacd) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=beta, ifixb=fix, maxit=100) odr.set_job(fit_type=0, deriv=2, var_calc=0) # Use user-supplied derivatives, but CHECK THEM!!! # ======== ODR RESULTS ========= output = odr.run() # Output of ODR run ref_B = output.beta # LSQ best-fit parameters err = output.sd_beta # Parameter errors (1-sigma) cov_B = output.cov_beta # Covariance matrix # The following was implemented for testing purposes to understand # how ODR was computing the covariance matrix, and how to generate # correlated random data using the Cholesky decomposition. # Most of this is now out of date. -JPT feb 2015 ''' # ODR covariance matrix print "ODR covariance:" print cov_B # Homemade covariance matrix from C = inv(JtJ), J = jacobian at optimum params. # NB: ODR wants the TRANSPOSE of J, so we need to transpose this guy J = jacb(ref_B,V).T for i in range(J.shape[0]): J[i,:] = (-1./Perr[i])*J[i,:] Jt = np.transpose(J) cov = np.linalg.inv(np.dot(Jt,J)) # Defn. of the covariance print 'Homemade cov (see Craigs PDF):' print cov cor = np.empty(cov.shape, dtype=float) # Correlation matrix. Need for correlated draws for i in range(cov.shape[0]): for j in range(cov.shape[1]): cor[i,j] = cov[i,j]/np.sqrt(np.dot(cov[i,i],cov[j,j])) # Spit results to stdout, will remove once it's finalized. print "cor (See Hughes & Hase pp. 94 eqn. 7.30):" print cor print "" print "Why does ODR cov_beta and homemade cov differ?" print "Because Hughes & Hase compute cov = inv(A)" print "Where Aij = 1/2 * d2 (chi_sq)/dBi dBj" print "Therefore one gets cor = 1/4 * inv(A)" print "As a result, multiply sqrt of diagonal elements" print "by 2 to compare with ODR std_beta." print "" print "spectrum of cor" # Check that cor is positive definite u,w = np.linalg.eig(cor) print u # Compute the Cholesky of the correlation matrix, # NB: Scipy returns a lower triangular Cholesky, we want upper triangular. U = np.linalg.cholesky(cor).T print "Cholesky(cor)" print U print "Best fit params:" print ref_B print "Standard error:" print err ''' # Print the results and plot if ODR was successful if output.stopreason[0] == 'Iteration limit reached': app.LOG_PRINT('ITERATION LIMIT REACHED, LSQ NOT CONVERGED!') else: RESULTS(ref_B, err, cov_B, output, f) PLOTS(ref_B, err, f, jacb, jacd, cov_B) return 0
def f23test(data, B, fix): F = np.zeros(2, dtype=float) # pdf C = np.zeros(2, dtype=float) # p-values B2 = np.zeros(2, dtype=float) # for the 2nd order EOS, assign K0 and V0 from user guesses B2[0] = B[0] B2[1] = B[-1] if data.EOS_type == GEOST_thermo.types().names[0]: # Figure out what EOS's to use # If birch murnaghan odr_model = odrpack.Model(fcn=GEOST_thermo.BM2_V, fjacb=GEOST_thermo.BM2_V_JACB, fjacd=GEOST_thermo.BM2_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B2, ifixb=[fix[0],fix[-1]]) odr.set_job(deriv=3) # Use user-supplied derivatives output = odr.run() # Output of ODR run ref_B2 = output.beta # LSQ best-fit parameters err_B2 = output.sd_beta # Parameter errors (1-sigma) f2 = GEOST_thermo.BM2_V(ref_B2,data.V) df2 = data.V.shape[0] - 2 odr_model = odrpack.Model(fcn=GEOST_thermo.BM3_V, fjacb=GEOST_thermo.BM3_V_JACB, fjacd=GEOST_thermo.BM3_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B, ifixb=fix) odr.set_job(deriv=3) # Use user-supplied derivatives, but CHECK THEM!!! output = odr.run() # Output of ODR run ref_B3 = output.beta # LSQ best-fit parameters err_B3 = output.sd_beta # Parameter errors (1-sigma) f3 = GEOST_thermo.BM3_V(ref_B3,data.V) df3 = data.V.shape[0] - 3 elif data.EOS_type == GEOST_thermo.types().names[1]: # If Natural strain odr_model = odrpack.Model(fcn=GEOST_thermo.NS2_V, fjacb=GEOST_thermo.NS2_V_JACB, fjacd=GEOST_thermo.NS2_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B2, ifixb=[fix[0],fix[-1]]) odr.set_job(deriv=3) # Use user-supplied derivatives output = odr.run() # Output of ODR run ref_B2 = output.beta # LSQ best-fit parameters err_B2 = output.sd_beta # Parameter errors (1-sigma) f2 = GEOST_thermo.NS2_V(ref_B2,data.V) df2 = data.V.shape[0] - 2 odr_model = odrpack.Model(fcn=GEOST_thermo.NS3_V, fjacb=GEOST_thermo.NS3_V_JACB, fjacd=GEOST_thermo.NS3_V_JACD) odr_data = odrpack.RealData(x=data.V, y=data.P, sx=data.Verr, sy=data.Perr) odr = odrpack.ODR(odr_data, odr_model, beta0=B, ifixb=fix) odr.set_job(deriv=3) # Use user-supplied derivatives, but CHECK THEM!!! output = odr.run() # Output of ODR run ref_B3 = output.beta # LSQ best-fit parameters err_B3 = output.sd_beta # Parameter errors (1-sigma) f3 = GEOST_thermo.NS3_V(ref_B3,data.V) df3 = data.V.shape[0] - 3 chisq_2 = float(0) chisq_3 = float(0) for i in range(data.P.shape[0]): # Compute the chi-squared for each EOS chisq_2 += (data.P[i] - f2[i])**2 chisq_3 += (data.P[i] - f3[i])**2 # Compute the F-statistic Fx23 = (chisq_2 - chisq_3)/(chisq_3/df3) # Use Scipy's built-in F-distribution methods F = f_dist.pdf(Fx23, 1, df3) # Compute the P-value C = 1 - f_dist.cdf(Fx23, 1, df3) x1 = np.linspace(0.01, 2*Fx23, 128) pdf23 = f_dist.pdf(x1, 1, df3) cdf23 = f_dist.cdf(x1, 1, df3) # Results plt.figure() fig = plt.gcf() fig.canvas.set_window_title("F-Test Results") plt.plot(x1, pdf23, 'r', linewidth=3, alpha=0.8) plt.plot(x1, cdf23, 'b', linewidth=3, alpha=0.8) plt.plot(Fx23, f_dist.pdf(Fx23, 1, df3), 'ko') plt.fill_between(x1, 0, pdf23, where=f_dist.cdf(Fx23, 1, df3)<cdf23, facecolor='red', alpha=0.2) plt.xticks(fontsize=14) plt.ylim([-0.01,1.01]) plt.title("F test for 2nd vs. 3rd order EOS", fontsize=14) plt.xlabel(r"$\left( \chi^{2}_{2} - \chi^{2}_{3} \right) / \left(\chi^{2}_{3} / \nu_{3} \right)$", fontsize=12) plt.ylabel(r"PDF/CDF") plt.legend(['PDF', 'CDF', r"$F_{X}$"], loc='upper right', numpoints=1) plt.text(Fx23, f_dist.pdf(Fx23, 1, df3)+0.05, "p-value= {:8.4f}".format(1-f_dist.cdf(Fx23, 1, df3)), fontsize=14) plt.tight_layout() return [chisq_2/df2, chisq_3/df3, Fx23, f_dist.cdf(Fx23, 1, df3)]