def getCFTiming(self, t, y): y = self.normalizeY(y) dt = t[1] - t[0] self.delayInterval = int(self.delay / dt) ntrun = int(np.floor(2000 / dt)) ymax = np.amax(y) halfy = np.where(y > ymax * self.gain * 0.9)[0] t0 = halfy[0] t1 = halfy[-1] + self.delayInterval f = self.simulateCFT(t, y, dt) yy = f(t[ntrun:-ntrun]) yys = yy[t0 - ntrun:t1 - ntrun] if len(yys) == 0: print(len(yy), [t0 - ntrun, t1 - ntrun]) x0 = self.crossFinder(yys) if x0 < 0: return -1 inte = [t[t0 + x0 - 1], t[t0 + x0 + 1]] if self.method == 'tomas': try: cft = optimize.toms748(f, inte[0], inte[1]) except: print(inte) raise ValueError('failed to get CFT') #cft = optimize.newton(lambda x : f(x), x0=(inte[0]+inte[1])/2) elif self.method == 'linear': x1 = inte[0] x2 = inte[1] k = (f(x2) - f(x1)) / (x2 - x1) cft = x1 - f(x1) / k return cft
def gamma_uncensored(gamma_obs, gammas): """ An uncensored gamma estimator. """ # Handle no observations if np.sum(gammas) == 0.0: gammas = np.ones_like(gammas) gammaCor = np.average(gamma_obs, weights=gammas) s = np.log(gammaCor) - np.average(np.log(gamma_obs), weights=gammas) def f(k): return np.log(k) - sc.polygamma(0, k) - s flow = f(1.0) fhigh = f(100.0) if flow * fhigh > 0.0: if np.absolute(flow) < np.absolute(fhigh): a_hat0 = 1.0 elif np.absolute(flow) > np.absolute(fhigh): a_hat0 = 100.0 else: a_hat0 = 10.0 else: a_hat0 = toms748(f, 1.0, 100.0) return [a_hat0, gammaCor / a_hat0]
def optim_b(cls, D, k, alpha, b_optim_min=0, b_optim_max=None, xtol=10**-12, **kwds): """Find optimal value of the characteristic length scale `b`. Parameters ---------- D : (N, N) array_like Distance matrix. b : float Characteristic length scale (positive value). alpha : Homophily value. b_optim_min : float Lower bound of the interval used in optimizing `b`. b_optim_max : float, optional Uppe bound of the interval used in optimizing `b`. If ``None`` then defaults to ``D.max()``. **kwds : Keyword parameters passed to :py:func:`scipy.optimize.brentq`. """ def b_optim(b): P = cls.prob_measure(D, b, alpha) Ek = P.sum(axis=1).mean() return k - Ek if b_optim_max is None: b_optim_max = D.max() b = toms748(b_optim, a=b_optim_min, b=b_optim_max, xtol=xtol, **kwds) return b
def solve_timestep_point(self, z_min, z_max, z_downstream, z_past, dt, dx, U, K, A, m, n): """Solves the transient equations E = K A^m S^n dz/dt = U - E dz/dt = U - K A^m S^n (z^j+1-z^j)/dt = U - K A^m ((z_i^j+1-z_i-1^j+1)/dx)^n We move all terms to one side: 0 = U - K A^m ((z_i^j+1-z_i-1^j+1)/dx)^n - (z^j+1-z^j)/dt we then assume this is a function z_predict = U - K A^m ((z_i^j+1-z_i-1^j+1)/dx)^n - (z^j+1-z^j)/dt and use a root finding algorithm to solve. We use Newton's method if n = 1 and the toms748 algorithm if n != 1. tom's is faster and guaranteed to converge, but does not work if function is not differentiable 4 times. we use upslope values of K, U, A for the discretization If n = 1 we can actually solve directly. 0 = U - K A^m ((z_f-z_ds)/dx) - (z_f-z_0)/dt 0 = U - K A^m z_f/dx + K A^m z_ds/dx - z_f/dt + z_0/dt K A^m z_f/dx + z_f/dt = U + K A^m z_ds/dx + z_0/dt z_f (K A^m/dx + 1/dt) = U + K A^m z_ds/dx + z_0/dt Args: uses all data members, no args Returns: Overwrites the elevation Author: Simon M Mudd Date: 18/08/2020 """ if n == 1: #z_future = optimize.newton(solve_timestep_differencer,z_past,args=(z_downstream,z_past,dt,dx,U,K,A,m,n)) SP_term = (K * A**m) / dx z_future = (U + SP_term * z_downstream + z_past / dt) / (SP_term + 1 / dt) else: z_future = optimize.toms748(solve_timestep_differencer, z_min, z_max, args=(z_downstream, z_past, dt, dx, U, K, A, m, n)) #print("Z_future is: ") #print(z_future) return z_future
def one_sigma_to_percent_error(percent, sigma): sigma_orders = [0, 1, 2, 3, 4, 5, 6] sigma_percents = [ 0., 68.2689492137, 95.4499736104, 99.7300203937, 99.9936657516, 99.9999426697, 99.9999998027 ] for i, sigma_order in enumerate(sigma_orders): if percent < sigma_percents[i]: break def func(error, percent, sigma, sigma_order): x = np.linspace(0, error, sigma_order * 100) return percent / 100 / 2 - simps( np.exp(-x**2 / 2 / sigma**2) / np.sqrt(2 * np.pi) / sigma, x) if sigma_order == 1: return toms748(func, 1e-2 * sigma, sigma_order * sigma, args=(percent, sigma, sigma_order)) else: return toms748(func, (sigma_order - 1) * sigma, sigma_order * sigma, args=(percent, sigma, sigma_order))
def squint(x, orbit, attitude, sin_az=0.0): """Find imaging time and squint (angle between LOS and velocity) for a target at position x.""" def daz(t): xs, _ = orbit.interpolate(t) # don't need velocity look = x - xs look *= 1.0 / np.linalg.norm(look) R = attitude.rotmat(t) err = sin_az - look.dot(R[:, 0]) #print("t, err =", t, err) return err # Find imaging time. #t = fsolve(daz, orbit.midTime, factor=10)[0] t = toms748(daz, orbit.startTime, orbit.endTime) #print("t0 =", t) # Compute squint. xs, vs = orbit.interpolate(t) vhat = vs / np.linalg.norm(vs) look = (x - xs) / np.linalg.norm(x - xs) return t, np.arcsin(look.dot(vhat))
td_TANK_ra = C_TANK_R.td(ss_1, ra = ra + ddd) dC_dR_TANK = (td_TANK_ra['C']/ td_TANK_ra['C'][Time-50] -1)*100 return dC_dR_HANK - dC_dR_TANK[0] sHTM_g = 0.2 ss['CR'] = ss['C'] * (1-sHTM_g) ss['sHTM'] = sHTM_g ss['avg_beta'] = np.vdot(ss['beta'], ss['pi_beta']) re_calib_beta = False ss_copy = ss.copy() args = (ss_copy, dTuni, HANK_MPC) res_HtM = optimize.toms748(MPC_calib, 0,1, args = args) ss['sHTM'] = res_HtM ss_copy['sHTM'] = res_HtM td_TANK = C_TANK.td(ss_copy, Tuni = dTuni) dCC_TANK = (td_TANK['C']/ td_TANK['C'][Time-50] -1)*100 ss_copy_ra = ss_copy.copy() ddd = - 0.0025 * 0.6**(np.arange(Time)) args = (ss_copy_ra, ddd, dC_dR_HANK) res_ra = optimize.toms748(R_calib, 0.005,3, args = args) td_ra = C_TANK.td(ss_copy, ra = ss['ra'] + ddd)
def calculate_apparent_D_with_noise(meas_erosion,meas_curv,half_length = 6, spacing = 1, S_c = 1.0, rho_ratio=2, topographic_uncert = 0.5, n_iterations = 5, use_brents = False): """This functions aim is to see whqat the actualk curvature would be if the profile were displaced Args: meas_erosion (float): the measured erosion rate (in m/yr) meas_curv (float): the curvature measured from the DEM half_length (float): The distance covered by the profile away rom the hillcrest spacing (float): The spacing of x in metres S_c (float): Critical slope (dimensionless) rho_ratio (float): ratio between rock and soil density topographic_uncert (float): the mean uncertainty in m of the topographic data n_iterations (int): the number of iterations you use to do the random uncertainty. use_brents (bool): if true, use brent's method instead of toms Returns: The ridgetop curvature in 1/m Author: Simon M Mudd Date: 15/05/2020 updated 04/05/2021 to include Brents method for unstable samples """ # first guess the diffusivity from the measured data D_apparent = -rho_ratio*meas_erosion/meas_curv print("The apparent D is:"+str(D_apparent)+" or "+str(D_apparent*1000)+" in m^2/kyr") # now we get the baseline sampling x_loc_baseline = set_profile_locations_half_length(half_length = half_length,spacing = spacing) # now solve the D needed to get the apparent D print("Right, going into the optimization loop") #print("By the way, the starting C is") #first_curv = curvature_difference_function(D_apparent, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv) #print("meas: "+str(meas_curv)+" and difference from the test curvature: "+str(first_curv)) #big = curvature_difference_function(D_apparent*2, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv) #small = curvature_difference_function(D_apparent*0.5, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv) #print("big:" +str(big)+" and small: "+str(small)) # plot the curvature function #D_vals = [D_apparent*0.5,D_apparent,D_apparent*2] #C_offset_vals = [] #for D in D_vals: # C_offset_vals.append( curvature_difference_function(D, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv) ) #print("C offsets are: ") #print(C_offset_vals) if(use_brents): print("I am going to use Brent's method to optimise") else: print("I am using the toms748 algorithm to optimise") # Run the optimisation root_1_list = [] for i in range(0,n_iterations): if use_brents: try: root_1 = optimize.brentq(curvature_difference_function_with_noise,0.000000000001,100,args=(x_loc_baseline,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert)) except ValueError: print("This iteration did not converge.") n_iterations=n_iterations+1 else: try: root_1 = optimize.toms748(curvature_difference_function_with_noise,0.000000000001,100,args=(x_loc_baseline,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert)) except ValueError: print("This iteration did not converge.") n_iterations=n_iterations+1 root_1_list.append(root_1) # now test #z = ss_nonlinear_elevation(x_loc_baseline,S_c = S_c,C_0 = meas_erosion , D=root ,rho_ratio = rho_ratio) #app_curv = fit_hilltop_curvature(x_loc_baseline,z) #print("Measured curvature is: "+str(meas_curv)+ " and the apparent curvature measured from a gridded sample is: "+str(app_curv)) # now to get a range, we want the minimum and maximum values # This is the maximum displacement of the data from the divide x_displace_max = displace_profile_locations_constant(x_loc_baseline,spacing/2) root_2_list = [] root_3_list = [] for i in range(0,n_iterations): if use_brents: try: root_2 = optimize.brentq(curvature_difference_function_with_noise,0.000000000001,100,args=(x_displace_max,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert)) except ValueError: print("This iteration did not converge.") else: try: root_2 = optimize.toms748(curvature_difference_function_with_noise,0.000000000001,100,args=(x_displace_max,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert)) except ValueError: print("This iteration did not converge.") root_1_list.append(root_2) max_D = max(root_1_list) min_D = min(root_1_list) med_D = st.median(root_1_list) D16 = np.percentile(root_1_list,16) D84 = np.percentile(root_1_list,84) print("Range of D:") print([min_D,med_D,max_D]) return [min_D,D16,med_D,D84,max_D]
def steady_state_concentraions(self, nxc): ''' Calculats the steady state concentration of carriers, provided the number of excess minoirty carriers by peturbing the number of excess majority carriers. This assumes a constant intrinsic carrier density. Parameters ---------- nxc : float the number of excess carrier densities Returns ------- ne: float the free electron concentration nh: float the free hole concentration nd: array like the number of defects in each state ''' def charges(mj): ''' calculations the change in majority carrier density this function doesn't really need to be here ''' if self.Nacc > self.Ndon: nh = np.array(mj, dtype=np.float64) ne = np.array(self.ne0 + nxc[i], dtype=np.float64) elif self.Ndon > self.Nacc: ne = np.array(mj, dtype=np.float64) nh = np.array(self.nh0 + nxc[i], dtype=np.float64) return ne, nh def charges_HD(Ef): # if the fermi energy leve is # negative the holes are the majority carrier if Ef < 0: qEfh = Ef nh = ni * np.exp(-1 * qEfh / self.Vt) ne = self.ne0 + nxc[i] qEfe = self.Vt * np.log(ne / ni) # if its bigger than zero the electrons are if Ef > 0: qEfe = Ef ne = ni * np.exp(qEfe / self.Vt) nh = self.nh0 + nxc[i] qEfh = -1 * self.Vt * np.log(nh / ni) return qEfe, qEfh, ne, nh def possion_hd(Ef): ''' determine the charge neutrality for high defect densities ''' qEfe, qEfh, ne, nh = charges_HD(Ef) # this is just a wrapper to set nte, which the following # possion function uses defect_charge = np.array(0, dtype=np.float64) # find the charge of the defects for _dft in self.defectlist: defect_charge += _dft.net_charge([qEfe, qEfh], temp) # add up all the charges return self.Ndon - ne - self.Nacc + nh + defect_charge def possion(mj): ''' determine the charge neutrality ''' # get the number of carriers ne, nh = charges(mj) # turns them into an quasi fermi energy level qEfe = self.Vt * np.log(ne / ni) qEfh = -1 * self.Vt * np.log(nh / ni) # this is just a wrapper to set nte, which the following # possion function uses defect_charge = np.array(0, dtype=np.float64) # find the charge of the defects for _dft in self.defectlist: defect_charge += _dft.net_charge([qEfe, qEfh], temp) # add up all the charges return self.Ndon - ne - self.Nacc + nh + defect_charge self.equlibrium_concentrations() if not isinstance(nxc, np.ndarray): nxc = np.array([nxc]) ne = np.zeros(nxc.shape[0]) nh = np.zeros(nxc.shape[0]) nd = [] nd = np.array([]) ni = self.ni Vt = self.Vt temp = self.temp mj = max(self.ne0, self.nh0) Nd = 0 for dft in self.defectlist: Nd += dft.Nd # need to do each carrier density individually # for low defect densities its all easy if Nd < 0.1 * mj: for i, nxc_i in enumerate(nxc): # initial guess of the number of excess majority carrier # then solve for charge conservation mj = newton(possion, np.array(mj + nxc[i], dtype=np.float64), maxiter=100, tol=1.48e-38) # get the values ne_i, nh_i = charges(mj) # save the values into the array ne[i] = ne_i nh[i] = nh_i # save the defect concentrations for _dft in self.defectlist: # nd.append(_dft.charge_state_concentration( # [Vt * np.log(ne_i / ni), -Vt * np.log(nh_i / ni)], temp)) nd = np.concatenate( (nd, _dft.charge_state_concentration( [Vt * np.log(ne_i / ni), -Vt * np.log(nh_i / ni)], temp))) else: for i, nxc_i in enumerate(nxc): Ef = toms748(possion_hd, -1, 1) qEfe, qEfh, ne_i, nh_i = charges_HD(Ef) # save the values into the array ne[i] = ne_i nh[i] = nh_i # save the defect concentrations for _dft in self.defectlist: nd = np.concatenate( (nd, _dft.charge_state_concentration([qEfe, qEfh], temp))) return ne, nh, nd
def equlibrium_concentrations(self): ''' Calculate the equlibrium carrier concentration Returns ------- ne0 : float the free electron concentration in the dark nh0 : float the free hole concentration in the dark ''' def charges(Ef): ne0, nh0 = ni * np.exp(np.array([Ef, -Ef]) / self.Vt) return ne0, nh0 def d_charges(Ef): ne0, nh0 = np.array([ni, -ni]) * \ np.exp(np.array([Ef, -Ef]) / self.Vt) / self.Vt return ne0, nh0 def possion(Ef): ne0, nh0 = charges(Ef) # this is just a wrapper to set nte, which the following # possion function uses defect_charge = 0 for _dft in self.defectlist: defect_charge += _dft.net_charge(Ef, self.temp) charge = self.Ndon - ne0 - self.Nacc + nh0 + defect_charge # print('\nsum and individuals for Ef=', # Ef, '{0:.2e}'.format(charge)) # print(self.Ndon - ne0 - self.Nacc + nh0 + defect_charge) # print(self.Vt * np.log(abs(self.Ndon - ne0 - # self.Nacc + nh0 + defect_charge - 1))) # print(self.Ndon, '{0:.2e}'.format(ne0), # self.Nacc, '{0:.2e}'.format(nh0), defect_charge) # plt.figure('norm') # plt.plot(Ef, (charge), 'r.') # plt.figure('log') # plt.plot(Ef, np.log(abs((charge)) + 1), 'r.') return charge def d_possion(Ef): dne0, dnh0 = d_charges(Ef) ne0, nh0 = charges(Ef) # this is just a wrapper to set nte, which the following # possion function uses defect_charge = 0 d_defect_charge = 0 for _dft in self.defectlist: defect_charge = _dft.net_charge(Ef + 0, self.temp) d_defect_charge += _dft.net_charge( Ef + 0.0001, self.temp) - _dft.net_charge( Ef + 0, self.temp) # f = self.Ndon - ne0 - self.Nacc + nh0 + defect_charge + 1 # fd = -dne0 + dnh0 + d_defect_charge # return fd / f return (-dne0 + dnh0 + d_defect_charge) # This line is to speed up calculations # recalculation of ni each time is quite slow. ni = self.ni # initial guess of majority carrier # mjc = newton(possion, abs(self.Nacc - self.Ndon), maxiter=100) # mjc = newton(possion, x0=Ef, maxiter=200, fprime=d_possion) Ef = toms748(possion, -1, 1) # new lets work out the details self.ne0, self.nh0 = charges(Ef) return self.ne0, self.nh0
rl_ = rl(x[0], x[2])**3 return numpy.array([ x[1], -(1 - MU) * x[0] / r3_ - MU * (x[0] - 1) / rl_, x[3], -(1 - MU) * x[2] / r3_ - MU * x[2] / rl_ ]) def x_star_equation(x): def x_star_equation_integral(z): return 1 / (numpy.e**(1.7 * (z**2)) + x) (integral, _) = quad(x_star_equation_integral, 0, 1) return integral - 0.3707355 * x x_star = toms748(x_star_equation, 0, 3) a = 1.2 * x_star b = 0 c = 0 d = 1 initial = numpy.array([a, b, c, d]) lower_bound = 0 upper_bound = T step = 0.1 _, space_plot = pyplot.subplots() _, velocities_plot = pyplot.subplots()
def _rootf(**kwargs): return optimize.toms748(k=1, **kwargs)