def Merge(self, prec=epsilon): """ Merge merges consecutive ramp(s) if they have the same acceleration """ if not self.isEmpty: if Abs((Abs(mp.log10(prec)) - (Abs(mp.floor(mp.log10(prec)))))) < Abs((Abs(mp.log10(prec)) - (Abs(mp.ceil(mp.log10(prec)))))): precexp = mp.floor(mp.log10(prec)) else: precexp = mp.ceil(mp.log10(prec)) aCur = self.ramps[0].a nmerged = 0 # the number of merged ramps for i in xrange(1, len(self.ramps)): j = i - nmerged if (Abs(self.ramps[j].a) > 1): if Abs((Abs(mp.log10(Abs(self.ramps[j].a))) - (Abs(mp.floor(mp.log10(Abs(self.ramps[j].a))))))) < Abs((Abs(mp.log10(Abs(self.ramps[j].a))) - (Abs(mp.ceil(mp.log10(Abs(self.ramps[j].a))))))): threshold = 10**(precexp + mp.floor(mp.log10(Abs(self.ramps[j].a))) + 1) else: threshold = 10**(precexp + mp.ceil(mp.log10(Abs(self.ramps[j].a))) + 1) else: threshold = 10**(precexp) if Abs(Sub(self.ramps[j].a, aCur)) < threshold: # merge ramps redundantRamp = self.ramps.pop(j) newDur = Add(self.ramps[j - 1].duration, redundantRamp.duration) self.ramps[j - 1].UpdateDuration(newDur) # merge switchpointsList self.switchpointsList.pop(j) nmerged += 1 else: aCur = self.ramps[j].a
def ceil_power(x, n=2): """ Return the value sign(x) * n^k such that n^k is the smallest value >= |x| for integer k. """ x = abs(x) logn = mp.log(x, n) if logn == mp.floor(logn): return x return mp.power(n, mp.floor(logn) + 1)
def prev_power(x, n=2): """ Return the value sign(x) * n^k such that n^k is the largest value < |x| for integer k. """ x = abs(x) logn = mp.log(x, n) if logn == mp.floor(logn): logn -= 1 return mp.power(n, mp.floor(logn))
def floor_power(x, n=2): """ Return the value sign(x) * n^k such that n^k is the largest value <= |x| for integer k. """ x = abs(x) return mp.power(n, mp.floor(mp.log(x, n)))
def figs(x, n=20, exp=0, sign=False): if (sign and x >= 0.0): s = ' ' else: s = '' # mp always returns '0.0' for zero. Bypass it using standard formats if (x == 0.0): fmt = '{{0:.{0}f}}'.format(n) # python uses two-digit exponent, but mp uses the least amount. Hard code it for zero if (exp): fmt += 'e+'+'0'*exp return s+fmt.format(0.0) # Convert significant figures to decimal places: # With exponent, integer part should be 1 figure, so it's n+1 # Without exponent, floor(log10(abs(x)))+1 gives the number of integer figures (except for zero) if (exp): tmp = s+mp.nstr(mp.mpf(x), n+1, strip_zeros=False, min_fixed=mp.inf, max_fixed=-mp.inf, show_zero_exponent=True) # Add zeros to the exponent if necessary exppos = tmp.find('e')+2 diff = exp-(len(tmp)-exppos) if (diff > 0): tmp = tmp[:exppos] + '0'*diff + tmp[exppos:] return tmp else: return s+mp.nstr(mp.mpf(x), int(mp.floor(mp.log10(abs(x))))+n+1, strip_zeros=False, min_fixed=-mp.inf, max_fixed=mp.inf)
def v(sigma, t, a0, ksumcache): if (sigma >= 0): return 1 + 0.4 * mp.power(9, sigma) / a0 + 0.346 * mp.power( 2, 3 * sigma / 2.0) / (a0**2) if (sigma < 0): K = int(mp.floor(-1 * sigma) + 3) return 1 + mp.power(0.9, mp.ceil(-1 * sigma)) * ksumcache[K]
def next_power(x, n=2): """ Return the value sign(x) * n^k such that n^k is the smallest value > |x| for integer k. """ x = abs(x) return mp.power(n, mp.floor(mp.log(x, n)) + 1)
def get_seq(self, n): seq = np.zeros(n, dtype=np.longlong) number = self.number for i in range(n): a = mp.floor(number) frac = number - a seq[i] = a if mp.almosteq(number, a): number = 0 else: number = mp.fdiv(1, frac) return seq
def segregate(num, precision): mp.dps = precision num = int(mp.floor(mp.sqrt(num)) + 1) cores = processor_cnt if num <= processor_cnt: cores = num - 1 num_mod = mp.fmod(num, cores) num_mods = [1 for _ in mp.arange(num_mod)] while len(num_mods) < cores: num_mods.append(0) num_div = mp.floor(mp.fdiv(num, cores)) num_divs, ip = [], 0 while len(num_divs) < cores: num_divs.append(num_div + num_mods[ip]) ip += 1 num_seg, place, seg = [num_divs[0]], num_divs[0], 1 while len(num_seg) < cores: place += num_divs[seg] num_seg.append(place) seg += 1 num_seg = [int(num_seg[i]) for i in range(len(num_seg))] return num_seg, cores
def v(sigma, s, t): T0 = s.imag T0dash = T0 + mp.pi() * t / 8.0 a0 = mp.sqrt(T0dash / (2 * mp.pi())) if (sigma >= 0): return 1 + 0.4 * mp.power(9, sigma) / a0 + 0.346 * mp.power( 2, 3 * sigma / 2.0) / (a0**2) if (sigma < 0): K = int(mp.floor(-1 * sigma) + 3) ksum = 0.0 for k in range(1, K + 2): ksum += mp.power(1.1 / a0, k) * mp.gamma(mp.mpf(k) / 2.0) return 1 + mp.power(0.9, mp.ceil(-1 * sigma)) * ksum
def dim_str(dim, units): """Format a dimension to a given unit.""" dim = to_mm(dim, units, True) prefix = "" if units == "ft": if dim >= mp.mpf(1): prefix = str(int(mp.floor(dim))) + "'" units = "in" dim = mp.frac(dim) * 12 dim = prefix + ("{:." + str(PRECS[units]) + "f}").format(float(mp.nstr(dim))) if units == "in": return dim + '"' return dim + " " + units
# Integration sol_BDF = solve_ivp( fun=system, t_span=t_span, y0=init_cond, method="BDF", dense_output=True, rtol=1e-6, atol=1e-8, first_step=(t_end - t_start) * 1e-5, args=params, ) t = np.logspace(start=-5, stop=np.log10(t_end), num=int(1e4)) y = sol_BDF.sol(t) # Save data in file data = np.stack((t, y[0], y[1], y[2], y[3], y[4]), axis=1) np.savetxt( join(dirname(abspath(__file__)), "plots/python.dat"), data, header="t \t i(t) \t a(t) \t m(t) \t z(t) \t s(t) \n", ) num = y[4][-1] ndigits = 3 - (int(mp.floor(mp.log10(abs(num)))) + 1 ) # Only works for numbers < 1. print("Stellar density after", t_end, "Gyr:", round(num, ndigits), "Mₒpc^(-2)")
def segregate(n): n = int(mp.floor(mp.sqrt(n)) + 1) n_d = int(mp.ceil(mp.fdiv(n, pro_cnt))) n_list = [[x, x + n_d] for x in range(1, n, n_d)] n_list[0][0], n_list[-1][1] = 2, n return n_list, len(n_list)
params = None # Integration sol_BDF = solve_ivp( fun=system, t_span=t_span, y0=init_cond, method="BDF", dense_output=True, rtol=1e-6, atol=1e-8, first_step=(t_end - t_start) * 1e-5, args=params, ) t = np.logspace(start=-5, stop=np.log10(t_end), num=int(1e4)) y = sol_BDF.sol(t) # Save data in file data = np.stack((t, y[0], y[1], y[2], y[3], y[4]), axis=1) np.savetxt( join(dirname(abspath(__file__)), "plots/python.dat"), data, header="t \t i(t) \t a(t) \t m(t) \t z(t) \t s(t) \n", ) num = y[4][-1] ndigits = 3 - (int(mp.floor(mp.log10(abs(num)))) + 1) # Only works for numbers < 1. print("Stellar density after", t_end, "Gyr:", round(num, ndigits), "Mₒpc^(-2)")
def truncate(n): decimal_places = mp.dps - 2 return mp.floor(n * 10**decimal_places) / (10**decimal_places)
order = list(range(1, mRys+1)) only_n = [1, 2, 3, 4, 5, 6, 7, 8, 9] # Requested accuracy (input) accuracy = list(map(mp.mpf, ['1e-16', '1e-16', '1e-15', '1e-15', '1e-14', '1e-14', '1e-13', '1e-13', '1e-12'])) # x step (input) dx = list(map(mp.mpf, ['0.008', '0.007', '0.009', '0.009', '0.012', '0.012', '0.017', '0.016', '0.023'])) fine_step = mp.mpf('0.001') # x value from which the asymptotic formula gives a relative error in roots and weights lower than the requested accuracy (computed with 0.01 precision) TMax = list(map(mp.mpf, ['38.80', '46.21', '50.71', '57.03', '60.32', '66.01', '68.69', '74.03', '76.26'])) # This would be with the same accuracy at all orders #accuracy = [mp.mpf('1e-16') for o in order] #TMax = list(map(mp.mpf, ['38.80', '46.21', '53.24', '59.64', '65.69', '71.51', '77.16', '82.68', '88.09'])) # Number of data points before reaching "TMax" nMap = [int(mp.floor(a/b)+1) for a,b in zip(TMax, dx)] # x values for the data points xlists = [[] for x in range(len(order))] for i in range(len(order)): for j in range(nMap[i]): prev = j*dx[i] xlists[i].append(list(frange(prev, (j+1)*dx[i], fine_step))) # reload the data from previous runs try: with open('tmpfile', 'rb') as f: data = pickle.load(f) except: data = {} for n,acc in zip(order, accuracy):
coeff[n][j][k].append([]) coeff[n][j][k][l] = tmp[m:m + npol[n]] m += npol[n] # Now it's time to actually test the fittings for each order of Rys polynomials for n in range(nmax): max_error = [zero, zero] # Test all the "data points" (x values) and mid-points too for ix in range(2 * nx[n] - 1): x = ix * dx[n] / 2 # Compute roots and weights roots, weights = rysroots(n + 1, x) # Select approximating polynomial ipol = polmap[n][int(mp.floor(x / dx[n]))] xoff = x - center[n][ipol] # For each root and weight calculate the value from the fitting polynomial roots_fit = [] weights_fit = [] for i in range(n + 1): pol = [] for j in range(fit_degree + 1): pol.insert(0, coeff[n][0][j][i][ipol]) roots_fit.append(mp.polyval(pol, xoff)) pol = [] for j in range(fit_degree + 1): pol.insert(0, coeff[n][1][j][i][ipol]) weights_fit.append(mp.polyval(pol, xoff)) # Obtain the maximum relative error error_r = max([abs((a - b) / b) for a, b in zip(roots_fit, roots)])
def floor(n): return mp.floor(n)