def get_vals(m1, m2, m3, a0, a2, e2, I): ''' calculates a bunch of physically relevant values ''' m12 = m1 + m2 m123 = m12 + m3 mu = m1 * m2 / m12 mu123 = m12 * m3 / m123 # calculate lk time n = np.sqrt(G * m12 / a0**3) t_lk0 = (1 / n) * (m12 / m3) * (a2 / a0)**3 * (1 - e2**2)**(3 / 2) # calculate jmin eta = mu / mu123 * np.sqrt(m12 * a0 / (m123 * a2 * (1 - e2**2))) eps_gr = 3 * G * m12**2 * a2**3 * (1 - e2**2)**(3 / 2) / (a0**4 * m3) def jmin_criterion(j): # eq 42, satisfied when j = jmin return ( 3 / 8 * (j**2 - 1) / j**2 * (5 * (np.cos(I) + eta / 2)**2 - (3 + 4 * eta * np.cos(I) + 9 * eta**2 / 4) * j**2 + eta**2 * j**4) + eps_gr * (1 - 1 / j)) def jmin_eta0(j): # set eta to zero, corresponds to test mass approx return (3 / 8 * (j**2 - 1) / j**2 * (5 * np.cos(I)**2 - 3 * j**2) + eps_gr * (1 - 1 / j)) jmin = brenth(jmin_criterion, 1e-15, 1 - 1e-15) jmin_eta0 = brenth(jmin_eta0, 1e-15, 1 - 1e-15) jmin_naive = np.sqrt(5 * np.cos(I)**2 / 3) emax = np.sqrt(1 - jmin**2) emax_eta0 = np.sqrt(1 - jmin_eta0**2) emax_naive = np.sqrt(1 - jmin_naive**2) return (t_lk0 * S_PER_UNIT) / S_PER_YR, emax, emax_eta0, emax_naive
def __call__(self, y, z): l = self.y[-1] bsurf = self.make_func( self.y / l * self.bn(0) + (1 - self.y / l) * self.bs(0), 'bsurf', self.y) if z == 0 and y == 0: # slope ill defined at (0,0); evaluate infinitesimally below the surface: z = -0.01 if z == self.z[0]: # slope also potentially ill defined at z= -H; evaluatejust above the bottom: z = 0.9999 * self.z[0] def fint(x): # function to help determine slope at bottom of vent. region return self.bn(0) - self.bs(-x * l) def fup(x): # function to help determine slope in vent. region return self.bs(z - x * y) - bsurf(y - z / x) def fdeep(x): # function to help determine slope below vent. region return self.bs(z - x * y) - self.bn(z + x * (l - y)) # first determine slope at bottom of vent. region here sbot = brenth(fint, 0., 1.) # than set slope for stuff above and below... if z > -sbot * (l - y): s = brenth(fup, 1e-10, 1.0) else: s = brenth(fdeep, -1.0, 1.0) return self.bs(z - s * y)
def ps_sp_solve(HP, phis, u, phi_ori): err = gv.phi_min_sys phi_max = (1 - 2 * phis * gv.r_sal) / (gv.r_res + gv.r_con * HP['pc']) - err sp1 = sco.brenth(ddf_phi, err, phi_ori, args=(phis, u, HP)) sp2 = sco.brenth(ddf_phi, phi_ori, phi_max, args=(phis, u, HP)) return sp1, sp2
def ps_sp_solve(HP, phis, u, phi_ori): err = phi_min_calc phi_max = (1 - 2 * phis) / (1 + HP['pc']) - err phi1 = sco.brenth(ddf_phi, err, phi_ori, args=(u, HP, phis)) phi2 = sco.brenth(ddf_phi, phi_ori, phi_max, args=(u, HP, phis)) return phi1, phi2
def calculate_simultaneous(self): """ Performs the power calculation for simultaneous comparisions """ delta = self.calculate_delta() if self.n is None: res = brenth(lambda ncp: self._calculate_simultaneous_power(ncp, self.alpha, self.n_groups) - self.power, a=2, b=1e7) self.n = math.ceil(res / delta) ncp = delta * self.n self.power = self._calculate_simultaneous_power(ncp, self.alpha, self.n_groups) self.beta = 1 - self.power elif self.power is None: ncp = delta * self.n self.power = self._calculate_simultaneous_power(ncp, self.alpha, self.n_groups) self.beta = 1 - self.power elif self.alpha is None: ncp = delta * self.n res = brenth(lambda alpha: self._calculate_simultaneous_power(ncp, alpha, self.n_groups) - self.power, a=0, b=1) self.alpha = res
def calculate_simultaneous(self): """ Performs the power calculation for simultaneous comparisions """ delta = self.calculate_delta() if self.n is None: res = brenth(lambda ncp: self._calculate_simultaneous_power( ncp, self.alpha, self.n_groups) - self.power, a=2, b=1e7) self.n = math.ceil(res / delta) ncp = delta * self.n self.power = self._calculate_simultaneous_power( ncp, self.alpha, self.n_groups) self.beta = 1 - self.power elif self.power is None: ncp = delta * self.n self.power = self._calculate_simultaneous_power( ncp, self.alpha, self.n_groups) self.beta = 1 - self.power elif self.alpha is None: ncp = delta * self.n res = brenth(lambda alpha: self._calculate_simultaneous_power( ncp, alpha, self.n_groups) - self.power, a=0, b=1) self.alpha = res
def calculate(self): if self.n is None: self._set_default_alpha() self._set_default_power() res = brenth(lambda n: self._calculate_power_unknown( n, self.m, self.sigma_ratio, self._alpha, self._beta), a=2, b=1e7) self.n = math.ceil(res) res = brenth(lambda beta: self._calculate_power_unknown( self.n, self.m, self.sigma_ratio, self._alpha, beta), a=0, b=1) self._beta = res self.update_beta() print(self.hypothesis) elif self.power is None: self._set_default_alpha() res = brenth(lambda beta: self._calculate_power_unknown( self.n, self.m, self.sigma_ratio, self._alpha, beta), a=1e-7, b=1 - 1e-7) self._beta = res self.update_beta() elif self.alpha is None: res = brenth(lambda alpha: self._calculate_power_unknown( self.n, self.m, self.sigma_ratio, alpha, self._beta), a=1e-7, b=1 - 1e-7) self._alpha = res self.update_alpha()
def ps_sp_solve(self, u, phi_ori): err = self.phi_min_sys HP = self.HP phis = self.phis phi_max = (1 - 2 * phis * self.r_sal) / (self.r_res + self.r_con * HP['pc']) - err sp1 = sco.brenth(self.ddf_phi, err, phi_ori, args=u) sp2 = sco.brenth(self.ddf_phi, phi_ori, phi_max, args=u) return sp1, sp2
def ps_sp_solve(self, u, phi_ori): HP = self.HP err = self.phi_min_calc phis = self.phis phi_max = (1 - 2 * self.phis) / (1 + HP['pc']) - err phi1 = sco.brenth(self.ddf_phi, err, phi_ori, args=u) phi2 = sco.brenth(self.ddf_phi, phi_ori, phi_max, args=u) return phi1, phi2
def EstimateBubbleWidth(profile): # Profile is expected to be stripped of nan's (wall nodes). assert not np.any(np.isnan(profile)) # Physical position is shifted due to wall location between # the fluid and no-slip node. x = np.arange(len(profile)) + 0.5 prof_int = interpolate.interp1d(x, profile, kind='cubic') y0 = optimize.brenth(prof_int, 0.5, len(profile) / 2) y1 = optimize.brenth(prof_int, len(profile) / 2, x[-1]) return y1 - y0
def calculate(self): """ Performs the power calculation """ if self.known_stdev: if self.n is None: self._set_default_alpha() self._set_default_power() self._calculate_n_known() self._calculate_power_known() self.n = self.n_1 + self.n_2 elif self.power is None: self._set_default_alpha() self._calculate_power_known() elif self.alpha is None: self._calculate_alpha_known() else: if self.n is None: self._set_default_alpha() self._set_default_power() alpha = self.alpha res = brenth(lambda n: self._calculate_power_unknown(n, alpha, self.theta, self.ratio, self._alpha_adjustment, self._beta_adjustment) - self.power, a=2, b=1e7) self.n_2 = math.ceil(res) self.n_1 = math.ceil(self.n_2 * self.ratio) self.n = self.n_1 + self.n_2 self.power = self._calculate_power_unknown(self.n_2, self.alpha, self.theta, self.ratio, self._alpha_adjustment, self._beta_adjustment) elif self.power is None: self._set_default_alpha() self.power = self._calculate_power_unknown(self.n_2, self.alpha, self.theta, self.ratio, self._alpha_adjustment, self._beta_adjustment) elif self.alpha is None: res = brenth(lambda alpha: self._calculate_power_unknown(self.n_2, alpha, self.theta, self.ratio, self._alpha_adjustment, self._beta_adjustment) - self.power, a=0, b=1) self.alpha = res
def plot_pseudo(): ''' plots pseudosynchronous frequency vs e ''' e_vals = np.linspace(0, 0.98, 200) f2 = 1 + 15*e_vals**2/2 + 45*e_vals**4/8 + 5*e_vals**6/16 f5 = 1 + 3 * e_vals**2 + 3 * e_vals**4 / 8 eta2 = 4 * f2 / (5 * f5 * (1 - e_vals**2)**(3/2)) pkl_fn = '1pseudosynchronous.pkl' if not os.path.exists(pkl_fn): print('Running %s' % pkl_fn) w_syncs_integ = [] w_syncs_sum = [] Nmax_max_0 = 10 * np.sqrt(1 + 0.98) / (1 - 0.98)**(3/2) for e in e_vals: Nmax_max = int(max(Nmax_max_0 * ( (np.sqrt(1 + e) / (1 - e)**(3/2)) / (np.sqrt(1 + 0.98) / (1 - 0.98)**(3/2)) ), 30)) def opt_func(w): return get_integral(w, e, Nmax=int(Nmax_max)) def opt_func_sum(w): coeffs = get_coeffs_fft(Nmax_max, 2, e) torques = get_torques(Nmax_max, w) return np.sum(coeffs**2 * torques) res = brenth(opt_func, 0, Nmax_max) res2 = brenth(opt_func_sum, 0, Nmax_max) print(e, res, res2) w_syncs_integ.append(res) w_syncs_sum.append(res2) with open(pkl_fn, 'wb') as f: pickle.dump((w_syncs_integ, w_syncs_sum), f) else: with open(pkl_fn, 'rb') as f: print('Loading %s' % pkl_fn) w_syncs_integ, w_syncs_sum = pickle.load(f) w_p = np.sqrt(1 + e_vals) / (1 - e_vals)**(3/2) # x = 1 - e_vals**2 x = e_vals plt.plot(x, w_syncs_sum / w_p, 'k', label='Exact') # plt.loglog(x, w_syncs_integ, label='Integral') plt.plot(x, eta2 / 0.691 / w_p, 'b', label=r'Eq.~(39)') plt.plot(x, f2 / (f5 * (1 - e_vals**2)**(3/2)) / w_p, 'r--', label=r'$\Omega_{\rm ps}^{\rm (Eq)}$') # plt.xticks([1 - 0.99**2, 1 - 0.9**2, 1 - 0.5**2], # labels=['0.99', '0.9', '0.5']) plt.xlabel(r'$e$') plt.ylabel(r'$\Omega_{\rm ps} / \Omega_{\rm p}$') plt.xlim(right=1.03) plt.legend(fontsize=14) plt.tight_layout() plt.savefig('1pseudosynchronous', dpi=200)
def xints(self,y): stb = self.stb stbtymax = self.stbtymax stbtxmax = self.stbtxmax stbtxmin = self.stbtxmin ymax = stb(stbtymax).imag() if y <= 0 or y>=ymax: return [] a = stb(brenth(lambda t: stb(t).imag() - y, stbtymax,1)).real() b = stb(brenth(lambda t: stb(t).imag() - y, 0,stbtymax)).real() return [(a,b)]
def MStep(self, posterior, data, mix_pi=None): x = self.data_numpy(data) post = posterior.sum() # sum of posteriors s = ddot(x-self.mu, self.inv_sigma) e1 = np.divide(self.df + self.p, self.df + s) e1post = posterior * e1 e1post = e1post[:, np.newaxis] e1 = e1[:, np.newaxis] loge1 = psi(0.5*(self.df + self.p)) - np.log(0.5*(self.df + s)) mu_1 = np.sum(x*e1post, axis=0)/np.sum(e1post, axis=0) tmp1 = x - self.mu tmp2 = tmp1 * e1post purr = tmp1[:, :, np.newaxis]*tmp2[:,np. newaxis, :] sigma_1 = np.sum(purr, axis=0)/post buzz = (np.sum(posterior*loge1) - np.sum(e1post, axis=0))/post #import ipdb; ipdb.set_trace() if np.any(buzz > -1.02): df_1 = self.df else: def fun1(t): return psi(0.5*t) - np.log(0.5*t) - 1 - buzz[0] df_1 = opt.brenth(fun1, 0.1, 50.) self.mu = mu_1 self.sigma = sigma_1 self.inv_sigma = np.linalg.inv(sigma_1) self.df = df_1 self.update_params()
def step(pt_id, time): particle = pt_arr[pt_id] timeslice = np.array([particle[0](time), particle[1](time), time]) if np.abs(timeslice[0]) >= np.abs(wall_x(time)): # new function for root-finding: f = lambda t: particle[0](t) - np.sign(particle[0](t)) * wall_x(t) # numerically calculate collision time t_col = brenth(f, time - dt, time) # particle and wall collide multiple times within interval (maybe) # if repeat: # try: # t_col1 = brenth(f, time - dt, t_col) # except: # pass # calculate collision position and momentum x_col = particle[0](t_col) p_col = 2 * m * np.sign(x_col) * wall_v(t_col) - particle[1](t_col) # build new particle new_particle = (build_pos(x_col, p_col, t_col), build_mom(x_col, p_col, t_col), pt_id) pt_arr[pt_id] = new_particle # may cause an infinite loop? return step(pt_id, time) return timeslice
def x_var(x, y, eps=1e-4): """ Returns the value of a, theta for arbitrary boundary conditions :param x: x coordinate :param y: y coordinate :param eps: precision value :return : value of (a, theta) :rtype: ndarray """ r = y / x if x < eps: theta = 2 * x / y else: def ini_cond(z): return r - (1 - np.cos(z)) / (z - np.sin(z)) theta = optimize.brenth(ini_cond, eps, 2 * np.pi - eps) a_val = 2 * y / (1 - np.cos(theta)) return np.array([a_val, theta])
def root(cls, spl, y, start, stop, scan_step=0.025): """计算样条曲线在y处于某个值时, 在[start, stop]范围内的交点 :param spl: 样条函数 :param y: :param start: 扫描的起点 :param stop: 求交范围的终点 :param scan_step: 扫描的精度, 默认0.05 :return: 根的列表 """ out = [] def func(x): return spl(x) - y # 在[start, stop]上搜索求根。 for i in np.arange(start - 0.1, stop + 0.1, step=scan_step): if (func(i) <= 0 < func(i + scan_step)) or (func(i) >= 0 > func(i + scan_step)): x0, r = brenth(func, i, i + scan_step, full_output=True) x_val = float(x0) out.append((x_val, y), ) # 当根的个数是技术的时候,分成1个或者3个及以上的情况来处理。 if len(out) % 2 != 0 and len(out) > 1: tmp = [] for p1, p2 in zip(out, out[1:]): if cls.distance(p1, p2) > 2.0: tmp.extend([p1, p2]) out = tmp[:] if len(out) == 1: out = [] return out
def snr_set(img0, target_snr=100, sig=2.0, stddev=2.0): """ Finds the level of noise which sets the integrated SNR within the 2-sigma contours to the specified value, via an interpolation. """ # Integrate signal for signal total_sig = img0.sum() # Set possible noise levels according to total signal levels = np.logspace(-10.0, 6.0, 101) * total_sig # Calculate the snr at all noise levels snrs = np.array([ snr_find(img0 + np.random.normal(0.0, n, img0.shape), n, sig=sig, stddev=stddev)[0] for n in levels ]) # Remove NaN values levels = levels[np.isfinite(snrs)] snrs = snrs[np.isfinite(snrs)] # Interpolate a function f(noise) = SNR(noise) - SNR_Target f = interp1d(levels, snrs - target_snr, kind='linear') # Find the root r = brenth(f, levels[0], levels[-1]) # Return both the noise levels and the mask from the convolved image return r, snr_find(img0, r, sig)[1]
def morning_twilight(self, mjd=None, twilight=None): """Return MJD (days) of morning twilight for MJD Parameters: ---------- mjd : np.int32, int Modified Julian Day (days) Returns: ------- morning_twilight : np.float64 time of twilight in MJD (days) """ if twilight is None: twilight = self.bright_twilight if (np.floor(np.float64(mjd)) != np.float64(mjd)): raise ValueError("MJD should be an integer") midnight_ish = (np.float64(mjd) - self.longitude / 15. / 24.) nextnoon_ish = midnight_ish + 0.5 twi = optimize.brenth(self._twilight_function, midnight_ish, nextnoon_ish, args=twilight) return (np.float64(twi))
def brent_iteration(target_function, x0, x1, max_iteration=100, tol=1e-7): # 首先判断求解区间是否为异号,若上下界函数取值不合理,调整上下界: if target_function(x0) * target_function(x1) > 0: x0, x1 = bound_adjustment(target_function, x0, x1) x1 = optimize.brenth(target_function, x0, x1, xtol=tol, rtol=tol, maxiter=max_iteration) return x1
def flash_PS_zs_bounded(self, P, Sm, zs, T_low=None, T_high=None, Sm_low=None, Sm_high=None): # Begin the search at half the lowest chemical's melting point if T_low is None: T_low = min(self.Tms) / 2 # Cap the T high search at 8x the highest critical point # (will not work well for helium, etc.) if T_high is None: max_Tc = max(self.Tcs) if max_Tc < 100: T_high = 4000 else: T_high = max_Tc * 8 temp_pkg_cache = [] def PS_error(T, P, zs, S_goal): if not temp_pkg_cache: temp_pkg = self.to(T=T, P=P, zs=zs) temp_pkg_cache.append(temp_pkg) else: temp_pkg = temp_pkg_cache[0] temp_pkg.flash(T=T, P=P, zs=zs) temp_pkg._post_flash() return temp_pkg.Sm - S_goal try: T_goal = brenth(PS_error, T_low, T_high, args=(P, zs, Sm)) return T_goal except ValueError: if Sm_low is None: pkg_low = self.to(T=T_low, P=P, zs=zs) pkg_low._post_flash() Sm_low = pkg_low.Sm if Sm < Sm_low: raise ValueError( 'The requested molar entropy cannot be found' ' with this bounded solver because the lower ' 'temperature bound %g K has an entropy (%g ' 'J/mol/K) higher than that requested (%g J/mol/K)' % (T_low, Sm_low, Sm)) if Sm_high is None: pkg_high = self.to(T=T_high, P=P, zs=zs) pkg_high._post_flash() Sm_high = pkg_high.Sm if Sm > Sm_high: raise ValueError( 'The requested molar entropy cannot be found' ' with this bounded solver because the upper ' 'temperature bound %g K has an entropy (%g ' 'J/mol/K) lower than that requested (%g J/mol/K)' % (T_high, Sm_high, Sm))
def M_sub(Ar, g): """Take an area ratio A/A* and return the corresponding subsonic Mach\ number using a variant of the Brent root finding method.""" if np.any(Ar < 1): raise ValueError("A/A* must be greater than or equal to 1") else: return opt.brenth(lambda M: F_Ar(M, g) - Ar, 10**-12, 1)
def velocity(self, r, theta, phi, mstar=0.5): mstar *= M_sun rcent = self.rcent * AU # Set up the coordinates. rr, tt, pp = numpy.meshgrid(r * AU, theta, phi, indexing='ij') mu = numpy.cos(tt) # Calculate mu0 at each r, theta combination. def func(mu0, r, mu, R_c): return mu0**3 - mu0 * (1 - r / R_c) - mu * (r / R_c) mu0 = mu * 0. for ir in range(rr.shape[0]): for it in range(rr.shape[1]): mu0[ir,it,0] = brenth(func,-1.0,1.0,args=(rr[ir,it,0], \ mu[ir,it,0],rcent)) v_r = -numpy.sqrt(G * mstar / rr) * numpy.sqrt(1 + mu / mu0) v_theta = numpy.sqrt(G*mstar/rr) * (mu0 - mu) * \ numpy.sqrt((mu0 + mu) / (mu0 * numpy.sin(tt))) v_phi = numpy.sqrt(G*mstar/rr) * numpy.sqrt((1 - mu0**2)/(1 - mu**2)) *\ numpy.sqrt(1 - mu/mu0) return numpy.array((v_r, v_theta, v_phi))
def coordinate(self, time): """Returns the coordinates as a function of time :param time: numpy array with the times :return : positons at the times ginve (in polar coordinates) :rtype: ndarray """ def intg(x): return 1/(1+self.e*np.cos(x))**2 def theta_f(th, val): res = quad(intg, 0.0, th) # note that the trajectory starts at the perihelion return res[0]-val theta = np.zeros_like(time) num_turns = np.zeros_like(time) for ind, x in enumerate(time): z = x a_max = self.theta_max if self.e < 1: z = np.remainder(z, self.period) num_turns[ind] = np.floor(x/self.period) a_max = 2*np.pi theta[ind] = optimize.brenth(theta_f, 0.0, a_max, args=(z,)) return np.array([theta, self.radial(theta), num_turns])
def cri_u_solve(phi, HP, phis): """ Try to bracket the u more strictly as going too high may lead to a reentrant behaviour. """ umin = 0.01 if ddf_u(umin, phi, HP, phis) > 0: print( "Problem ddf_u is positive even al low u. Maybe ehs not for LCST?") print("phi= {:.4f}, u = {:.4f}".format(phi, umin)) return umax = umin * 1.25 while True: if ddf_u(umax, phi, HP, phis) > 0: break else: umax *= 1.25 if umax > 10: print( "Problem ddf_u is negative even al high u. Maybe ehs not for LCST?" ) print("phi= {:.4f}, u = {:.4f}".format(phi, umax)) return result = sco.brenth(ddf_u, umin, umax, args=(phi, HP, phis)) return result
def velocity(self, r, theta, phi, mstar=0.5): mstar *= M_sun rcent = self.rcent * AU # Set up the coordinates. rr, tt, pp = numpy.meshgrid(r*AU, theta, phi,indexing='ij') mu = numpy.cos(tt) # Calculate mu0 at each r, theta combination. def func(mu0,r,mu,R_c): return mu0**3-mu0*(1-r/R_c)-mu*(r/R_c) mu0 = mu*0. for ir in range(rr.shape[0]): for it in range(rr.shape[1]): mu0[ir,it,0] = brenth(func,-1.0,1.0,args=(rr[ir,it,0], \ mu[ir,it,0],rcent)) v_r = -numpy.sqrt(G*mstar/rr)*numpy.sqrt(1 + mu/mu0) v_theta = numpy.sqrt(G*mstar/rr) * (mu0 - mu) * \ numpy.sqrt((mu0 + mu) / (mu0 * numpy.sin(tt))) v_phi = numpy.sqrt(G*mstar/rr) * numpy.sqrt((1 - mu0**2)/(1 - mu**2)) *\ numpy.sqrt(1 - mu/mu0) return numpy.array((v_r, v_theta, v_phi))
def critical_relative_AMD_resonance_overlap(alpha, gamma, mutot): r""" The critical value of 'relative AMD', :math:`{\cal C} = C/\Lambda_\mathrm{out}`, of a planet pair above which resonance overlap can occur based on the resonance overlap criterion of Hadden & Lithwick (2018) Arguments --------- alpha : float The semi-major axis ratio, :math:`\alpha=a_\mathrm{in}/a_\mathrm{out}` of the planet pair. gamma : float The mass ratio of the planet pair, :math:`\gamma = m_\mathrm{in}/m_\mathrm{out}`. mutot : float The total mass of the planet pair relative to the star, i.e., :math:`(\mu_\mathrm{in} + \mu_\mathrm{out}) / M_*` Returns ------- Ccrit : float The value of the the critical AMD (:math:`C_c(\alpha,\gamma)` in the notation of `Laskar & Petit (2017) <https://ui.adsabs.harvard.edu/abs/2017A%26A...605A..72L/abstract>`_ """ e0 = np.min((1, 1 / alpha - 1)) ec = brenth(_F_for_res_overlap, 0, e0, args=(alpha, gamma, mutot)) fByg = alpha**(0.825) denom = np.sqrt((1 - ec * ec) * fByg**2 + ec * ec * alpha * gamma * gamma) e1c = gamma * np.sqrt(alpha) * ec / denom curlyC = gamma * np.sqrt(alpha) * (1 - np.sqrt(1 - ec * ec)) + ( 1 - np.sqrt(1 - e1c * e1c)) return curlyC
def critical_relative_AMD(alpha, gamma): r""" The critical value of 'relative AMD', :math:`{\cal C} = C/\Lambda_\mathrm{out}`, of a planet pair above which intersecting orbits are allowed. See Equation 29 of `Laskar & Petit (2017) <https://ui.adsabs.harvard.edu/abs/2017A%26A...605A..72L/abstract>`_ Arguments --------- alpha : float The semi-major axis ratio, :math:`\alpha=a_\mathrm{in}/a_\mathrm{out}` of the planet pair. gamma : float The mass ratio of the planet pair, :math:`\gamma = m_\mathrm{in}/m_\mathrm{out}`. Returns ------- Ccrit : float The value of the the critical AMD (:math:`C_c(\alpha,\gamma)` in the notation of `Laskar & Petit (2017) <https://ui.adsabs.harvard.edu/abs/2017A%26A...605A..72L/abstract>`_ """ e0 = np.min((1, 1 / alpha - 1)) ec = brenth(_F, 0, e0, args=(alpha, gamma)) e1c = np.sin(np.arctan(gamma * ec / np.sqrt(alpha * (1 - ec * ec)))) curlyC = gamma * np.sqrt(alpha) * (1 - np.sqrt(1 - ec * ec)) + ( 1 - np.sqrt(1 - e1c * e1c)) return curlyC
def flash_TVF_zs(self, T, VF, zs): assert 0 <= VF <= 1 Psats = self._Psats(T=T) Pbubble = self.P_bubble_at_T(T=T, zs=zs, Psats=Psats) if VF == 0: P = Pbubble else: diff = 1E-7 Pmax = Pbubble # EOSs do not solve at very low pressure if self.use_phis: Pmin = max(Pmax * diff, 1) else: Pmin = Pmax * diff P = brenth(self._T_VF_err, Pmin, Pmax, args=(T, zs, Psats, Pmax, VF)) self.__TVF_solve_cache = None # P = brenth(self._T_VF_err, Pdew, Pbubble, args=(T, VF, zs, Psats)) V_over_F, xs, ys = self._flash_sequential_substitution_TP(T=T, P=P, zs=zs, Psats=Psats) return 'l/g', xs, ys, V_over_F, P
def project(self, p, s0, ds=1, s_lim=20, verbose=False): def s_fun(si): hi, nc = self.heading(si) dp = p - self.p(si) #return float(np.cross(dp, nc)) return float(dp[0] * nc[1] - dp[1] * nc[0]) smin = s0 smax = s0 cnt_lim = s_lim / ds cnt = 0 while np.sign(s_fun(smin)) == np.sign(s_fun(smax)) and cnt < cnt_lim: smin = np.max((0, smin - ds)) smax = np.min((smax + ds, self.length)) cnt = cnt + 1 if cnt < cnt_lim: # Found sign change in interval, do a line-search si = brenth(s_fun, smin, smax) else: # No sign change, evaluate boundary points and choose closest if verbose: warnings.warn('Warning: Outside bounds') dpmin = p - self.p(smin) dpmax = p - self.p(smax) if dpmin.dot(dpmin) < dpmax.dot(dpmax): si = smin else: si = smax dp = p - self.p(si) hi, _ = self.heading(si) dp = np.cross(hi, dp) return si, dp
def get_I1(I0, eta): ''' given total inclination between Lout and L, returns I_tot ''' def I2_constr(_I2): return np.sin(_I2) - eta * np.sin(I0 - _I2) I2 = opt.brenth(I2_constr, 0, np.pi, xtol=1e-12) return np.degrees(I0 - I2)
def conditionalCopula1(args): v, f, theta = args while True: u = np.random.uniform() # source def g(t,f,u,theta): return ( f(theta, u + 10e-7, t) - f(theta, u, t) )/ 10e-7 g = partial(g, f = f, u = v, theta = theta) try: t = spo.brenth(lambda x: g(x) - u, 10e-7, 1-10e-7, xtol = 10e-7) # t = spo.newton_krylov(F = lambda x: g(x) - u, xin = (1-u))[0] # t = spo.minimize(fun = lambda x: (g(x) - u)**2, x0 = (u,), bounds = [(10e-7,1-10e-7)], tol = 10e-16).x[0] except Exception as e: print(e, u, v, sep = " ") v = np.random.uniform() else: break return (v, t)
def get_eI2(e1, I1, eta0, ltot_i): ''' uses law of sines + conservation of Ltot to give e2, I2 ''' opt_func = lambda e2: ltot(e1, I1, e2, eta0) - ltot_i e2max = np.sqrt(1 - (eta0 * np.sin(I1))**2 * (1 - e1**2)) e2 = opt.brenth(opt_func, 0, e2max - 1e-7) I2 = get_I2(e1, I1, e2, eta0) return e2, I2
def gp(self, p): # solve p(g(ta),ta) = pcrit ''' Time and distance where dpdt=0 for fluid pressure. Parameters ---------- p : float Pressure. Returns ------- t : float Time. r : float Distance. Notes ----- Returns first root (point A) or NaN if p less than bifurcation point pressure. Computed using root solve. ''' # if p less than bifurcation pressure, return NaN if p < self.pstar: return float('NaN') # compute root ta = brenth(self.gp0, 1. + 1.e-8, self.tstar, args=(p, )) return ta, self.gt(ta)
def SolveForRedshift(t): ''' Take a lookback time in [Gyr] and return the corresponding redshift ''' f_to_solve = lambda z_f: t - LookbackTime(z_f) if f_to_solve(0.) * f_to_solve(10.) > 0.: raise ValueError(Error_Msg('ImproperBinSize')) else: root = optimize.brenth(f_to_solve, 0., 10.) return root
def liq_ice_air_A_h_fixed_rh_wmo(rh_wmo,eta,p): import pyteos_air.liq_ice_air as liq_ice_air import scipy.optimize as optimize A_rh_function=(lambda massfraction_air: massfraction_air / (massfraction_air + rh_wmo * (1.0 - massfraction_air))) A_function=(lambda A: A - A_rh_function(np.squeeze(liq_ice_air.sat.massfraction_air(liq_ice_air.h.temperature(A,eta,p),p)))) if np.sign(A_function(0.95)*A_function(1.0))<0.0: A=optimize.brenth(A_function,0.95,1.0) else: try: A_min=optimize.minimize_scalar(A_function,bracket=[0.95,1.0]).x if np.sign(A_function(A_min)*A_function(1.0))<0.0: A=optimize.brenth(A_function,A_min,1.0) else: A=1.0 except RuntimeError: A=0.95 return A
def BSImpVolNormal( IsCall, Fwd, Strike, Texp, Rd, Price ): '''Calculates the normal-model implied vol to match the option price.''' def ArgFunc( Vol ): PriceCalc = BSOptFwdNormal( IsCall, Fwd, Strike, Vol, Texp, Rd ) return PriceCalc - Price Vol = brenth( ArgFunc, 0.0000001, Fwd ) return Vol
def _Tsats(self, P): Tsats = [] for i in self.VaporPressures: try: Tsats.append(i.solve_prop(P)) except: error = lambda T: i.extrapolate_tabular(T) - P Tsats.append(brenth(error, i.Tmax, i.Tmax*5)) return Tsats
def ammonia_vapor_mass_fraction(self): """ Mass fraction of ammonia yNH3 within the vapor phase, calculated from the temperature in [°C] and the pressure in [bar]. """ def f_to_solve(yNH3): # Function created only for calculation purpose return self.dew_point_temperature(self._pressure, yNH3)\ -self._temperature # And solving to obtain the solution, using the Brent method. return sp.brenth(f_to_solve,0.0,1.0)
def calculate(self): if self.n is None: self._set_default_alpha() self._set_default_power() res = brenth(lambda n: self._calculate_power_unknown(n, self.m, self.sigma_ratio, self._alpha, self._beta), a=2, b=1e7) self.n = math.ceil(res) res = brenth(lambda beta: self._calculate_power_unknown(self.n, self.m, self.sigma_ratio, self._alpha, beta), a=0, b=1) self._beta = res self.update_beta() print(self.hypothesis) elif self.power is None: self._set_default_alpha() res = brenth(lambda beta: self._calculate_power_unknown(self.n, self.m, self.sigma_ratio, self._alpha, beta), a=1e-7, b=1 - 1e-7) self._beta = res self.update_beta() elif self.alpha is None: res = brenth(lambda alpha: self._calculate_power_unknown(self.n, self.m, self.sigma_ratio, alpha, self._beta), a=1e-7, b=1 - 1e-7) self._alpha = res self.update_alpha()
def BSImpVolSimple( IsCall, Spot, Strike, Texp, Rd, Rf, Price ): '''Calculates Black-Scholes implied volatility from a European price. It uses Brent rootfinding and assumes the vol is between 0.0000001 and 1.''' def ArgFunc( Vol ): PriceCalc = BSOpt( IsCall, Spot, Strike, Vol, Texp, Rd, Rf ) return PriceCalc - Price Vol = brenth( ArgFunc, 0.0000001, 1 ) return Vol
def optimise(likelihood, partials_a, partials_b, min_brlen=0.00001, max_brlen=10, verbose=True): """ Optimise ML distance between two partials. min and max set brackets """ from scipy.optimize import brenth wrapper = OptWrapper(likelihood, partials_a, partials_b, (min_brlen+max_brlen)/2.) brlen = 0.5 n=brenth(wrapper.get_dlnl, min_brlen, max_brlen) if verbose: logger.info(wrapper) return n, -1/wrapper.get_d2lnl(n)
def flash_PVF_zs(self, P, VF, zs): try: # In some caases, will find a false root - resort to iterations which # are always between Pdew and Pbubble if this happens T = brenth(self._P_VF_err_2, min(self.Tms), min(self.Tcs), args=(P, VF, zs), maxiter=500) V_over_F, xs, ys = self._flash_sequential_substitution_TP(T=T, P=P, zs=zs) assert abs(V_over_F-VF) < 1E-6 except: T = ridder(self._P_VF_err, min(self.Tms), min(self.Tcs), args=(P, VF, zs)) V_over_F, xs, ys = self._flash_sequential_substitution_TP(T=T, P=P, zs=zs) return 'l/g', xs, ys, V_over_F, T
def P_dew_at_T(self, T, zs, Psats=None): Psats = self._Psats(Psats, T) Pmax = self.P_bubble_at_T(T, zs, Psats) diff = 1E-7 # EOSs do not solve at very low pressure if self.use_phis: Pmin = max(Pmax*diff, 1) else: Pmin = Pmax*diff P_dew = brenth(self._T_VF_err, Pmin, Pmax, args=(T, zs, Psats, Pmax, 1)) self.__TVF_solve_cache = None return P_dew
def yints(self,x): stb = self.stb stbtymax = self.stbtymax stbtxmax = self.stbtxmax stbtxmin = self.stbtxmin xmax = stb(stbtxmax).real() xmin = stb(stbtxmin).real() eta0 = stb(1) eta1 = stb(0) if x <= xmin or x>=xmax: return [] b = stb(brenth(lambda t: stb(t).real() - x, stbtxmax,stbtxmin)).imag() if eta0 <= x and x <= eta1: a = 0 else: if eta1 < x: a = stb(brenth(lambda t: stb(t).real() - x, 0,stbtxmax)).imag() if x < eta0: a = stb(brenth(lambda t: stb(t).real() - x, stbtxmin,1)).imag() return [(a,b)]
def flash_PVF_zs(self, P, VF, zs): assert 0 <= VF <= 1 Tsats = self._Tsats(P) # handle one component if self.N == 1: return 'l/g', [1.0], [1.0], VF, Tsats[0] T = brenth(self._P_VF_err, min(Tsats)*(1+1E-7), max(Tsats)*(1-1E-7), args=(P, VF, zs)) Psats = self._Psats(T) Ks = [K_value(P=P, Psat=Psat) for Psat in Psats] V_over_F, xs, ys = flash_inner_loop(zs=zs, Ks=Ks) return 'l/g', xs, ys, V_over_F, T
def ci_corr(self, sig=.05, upper_bound=None, lower_bound=None): """ Returns the confidence intervals for the correlation coefficient Parameters ---------- sig : float The significance level. Default is .05 upper_bound : float Maximum value the upper confidence limit can be. Default is 99% confidence limit assuming normality. lower_bound : float Minimum value the lower condidence limit can be. Default is 99% confidence limit assuming normality. Returns ------- interval : tuple Confidence interval for the correlation """ endog = self.endog nobs = self.nobs self.r0 = chi2.ppf(1 - sig, 1) point_est = np.corrcoef(endog[:, 0], endog[:, 1])[0, 1] if upper_bound is None: upper_bound = min(.999, point_est + \ 2.5 * ((1. - point_est ** 2.) / \ (nobs - 2.)) ** .5) if lower_bound is None: lower_bound = max(- .999, point_est - \ 2.5 * (np.sqrt((1. - point_est ** 2.) / \ (nobs - 2.)))) llim = optimize.brenth(self._ci_limits_corr, lower_bound, point_est) ulim = optimize.brenth(self._ci_limits_corr, point_est, upper_bound) return llim, ulim
def StrikeFromDelta( IsCall, Spot, Vol, Texp, Rd, Rf, Delta ): '''Calculates the strike of a European vanilla option gives its Black-Scholes Delta. It assumes the Delta is an over-ccy spot Delta.''' def ArgFunc( Strike ): DeltaCalc = BSDelta( IsCall, Spot, Strike, Vol, Texp, Rd, Rf ) return DeltaCalc - Delta LoStrike = Spot * exp( ( Rd - Rf ) * Texp - 4 * Vol * sqrt( Texp ) ) HiStrike = Spot * exp( ( Rd - Rf ) * Texp + 4 * Vol * sqrt( Texp ) ) Strike = brenth( ArgFunc, LoStrike, HiStrike ) return Strike
def flash_PS_zs_bounded(self, P, Sm, zs, T_low=None, T_high=None, Sm_low=None, Sm_high=None): # Begin the search at half the lowest chemical's melting point if T_low is None: T_low = min(self.Tms)/2 # Cap the T high search at 8x the highest critical point # (will not work well for helium, etc.) if T_high is None: max_Tc = max(self.Tcs) if max_Tc < 100: T_high = 4000 else: T_high = max_Tc*8 temp_pkg_cache = [] def PS_error(T, P, zs, S_goal): if not temp_pkg_cache: temp_pkg = self.to(T=T, P=P, zs=zs) temp_pkg_cache.append(temp_pkg) else: temp_pkg = temp_pkg_cache[0] temp_pkg.flash(T=T, P=P, zs=zs) temp_pkg._post_flash() return temp_pkg.Sm - S_goal try: T_goal = brenth(PS_error, T_low, T_high, args=(P, zs, Sm)) return T_goal except ValueError: if Sm_low is None: pkg_low = self.to(T=T_low, P=P, zs=zs) pkg_low._post_flash() Sm_low = pkg_low.Sm if Sm < Sm_low: raise ValueError('The requested molar entropy cannot be found' ' with this bounded solver because the lower ' 'temperature bound %g K has an entropy (%g ' 'J/mol/K) higher than that requested (%g J/mol/K)' %( T_low, Sm_low, Sm)) if Sm_high is None: pkg_high = self.to(T=T_high, P=P, zs=zs) pkg_high._post_flash() Sm_high = pkg_high.Sm if Sm > Sm_high: raise ValueError('The requested molar entropy cannot be found' ' with this bounded solver because the upper ' 'temperature bound %g K has an entropy (%g ' 'J/mol/K) lower than that requested (%g J/mol/K)' %( T_high, Sm_high, Sm))
def VCACP(engine,app): engine.cache.pop('pt_mesh',None) nelectron=app.BZ.rank['k']*len(engine.operators['csp'])*engine.filling fx=lambda omega: -sum(imag((trace(engine.gf_vca_kmesh(omega+app.eta*1j,app.BZ.mesh['k']),axis1=1,axis2=2))))/pi for i,(a,b,deg) in enumerate(app.e_degs): buff=0 if i<2: buff+=integration(fx,a,b,deg=deg) else: Fx=lambda omega: integration(fx,a,omega,deg=deg)+buff-nelectron #app.mu=newton(Fx,engine.mu,fprime=fx,tol=app.error) app.mu=brenth(Fx,app.a,app.b,xtol=app.error) engine.mu=app.mu print 'mu,error:',engine.mu,Fx(engine.mu)
def flash_TVF_zs(self, T, VF, zs): assert 0 <= VF <= 1 Psats = self._Psats(T) # handle one component if self.N == 1: return 'l/g', [1.0], [1.0], VF, Psats[0] if VF == 0: P = bubble_at_T(zs, Psats) elif VF == 1: P = dew_at_T(zs, Psats) else: P = brenth(self._T_VF_err, min(Psats)*(1+1E-7), max(Psats)*(1-1E-7), args=(VF, zs, Psats)) Ks = [K_value(P=P, Psat=Psat) for Psat in Psats] V_over_F, xs, ys = flash_inner_loop(zs=zs, Ks=Ks) return 'l/g', xs, ys, V_over_F, P
def water_equilibrium_vapor_temperature(self, pressure): """ Equilibrium vapor temperature of pure water, in [°C] at a given pressure, in [bar], between 0.008 bar and 217 bar. """ # We calculate the corresponding value of the temperature, firstly in # defining the function to solve in order to find the temperature value. def f_to_solve(temp): # We look for the root of the square of the function, and not of the # function itself, in order to go quicker to the solution and to # avoid any problem with the initial sign of the difference. return self.water_equilibrium_vapor_pressure(temp)-pressure # Solving by a Brent method within a temperature range corresponding to # the one going from the triple temperature to the critical one. teq = sp.brenth(f_to_solve, 1.0, 374.) # And result return teq
def biexponential_transform(X, a, b, c, d, f, w, max_ite=5000): # TODO: Find a faster way Y = np.zeros(X.shape) for i in range(len(X)): x = X[i] # We can probably get rid of this part. step = 0.5 for _ in range(max_ite): step *= 1.5 bf1 = biexponential_(-step, a, b, c, d, f, w) bf2 = biexponential_(step, a, b, c, d, f, w) if (bf1 - x) * (bf2 - x) <= 0: break else: _LG.info("Failed to find range.") Y[i] = brenth(lambda x_: biexponential_(x_, a, b, c, d, f, w) - x, -step, step) return Y
def logicle_(X, w, r, d, scale): def _func(p, w): # TODO: Give appropriate name return -w + 2 * p * np.log(p) / (p + 1) d = d * np.log(10) scale = scale / d p = brenth(_func, 0.99, 1000, args=(w,)) # If w > 6, then this will raise a = r * np.exp(-(d - w)) b = 1 c = a * p * p d = 1 / p f = a * (p * p - 1) # Apply biexponential transform here. y = biexponential_transform(X, a, b, c, d, f, w) y = y * scale y[y < 0] = 0 return y
def flash_TS_zs_bounded(self, T, Sm, zs, P_low=None, P_high=None, Sm_low=None, Sm_high=None): # Begin the search at half the lowest chemical's melting point if P_high is None: P_high = self.Pbubble(T, zs) if P_low is None: P_low = 1E-5 # min pressure # P_high = max(self.Pcs)*10 temp_pkg_cache = [] def TS_error(P, T, zs, S_goal): if not temp_pkg_cache: temp_pkg = self.to(T=T, P=P, zs=zs) temp_pkg_cache.append(temp_pkg) else: temp_pkg = temp_pkg_cache[0] temp_pkg.flash(T=T, P=P, zs=zs) temp_pkg._post_flash() return temp_pkg.Sm - S_goal try: P_goal = brenth(TS_error, P_low, P_high, args=(T, zs, Sm)) return P_goal except ValueError: if Sm_low is None: pkg_low = self.to(T=T, P=P_low, zs=zs) pkg_low._post_flash() Sm_low = pkg_low.Sm if Sm > Sm_low: raise ValueError('The requested molar entropy cannot be found' ' with this bounded solver because the lower ' 'pressure bound %g Pa has an entropy (%g ' 'J/mol/K) lower than that requested (%g J/mol/K)' %( P_low, Sm_low, Sm)) if Sm_high is None: pkg_high = self.to(T=T, P=P_high, zs=zs) pkg_high._post_flash() Sm_high = pkg_high.Sm if Sm < Sm_high: raise ValueError('The requested molar entropy cannot be found' ' with this bounded solver because the upper ' 'pressure bound %g Pa has an entropy (%g ' 'J/mol/K) upper than that requested (%g J/mol/K)' %( P_high, Sm_high, Sm))
def calculate(self): if self.n is None: if self.alpha is None: self.alpha = 0.05 if self.power is None: power = 0.8 else: power = self.power beta = 1 - power df = self.df delta = optimize.brenth(lambda delta: self._beta(df, delta, self.alpha) - beta, a=0.000001, b=1e7) n = delta / self._denom self.n = math.ceil(n) self.beta = beta self.power = power
def rootalt(f,a,b): eps=(b-a)/64.0 turn=0 N_iter=10 while abs(a-b)>eps and N_iter<>0: N_iter-=1 try: #return fmin_cg(f,(a+b)/2.0)[0] return brenth(f,a,b) except ValueError: if turn==0: a=a+eps turn=1 else: b=b+eps turn=0 #return root2(f,a,b) return None
def root(f,a,b): a_init=a b_init=b eps=(b-a)/16.0 turn=0 N_iter=12 while abs(a-b)>eps and N_iter<>0 and f(a)*f(b)>0: N_iter-=1 if turn==0: a=a+eps turn=1 else: b=b-eps turn=0 try: return brenth(f,a,b) except ValueError: return fminbound(f,a_init,b_init)