def gradient(self, arg): return np.array([ Decimal.exp(arg[0] + Decimal(3) * arg[1] - Decimal(0.1)) + Decimal.exp(arg[0] - Decimal(3) * arg[1] - Decimal(0.1)) - Decimal.exp(-arg[0] - Decimal(0.1)), 3 * (Decimal.exp(arg[0] + Decimal(3) * arg[1] - Decimal(0.1)) - Decimal.exp(arg[0] - Decimal(3) * arg[1] - Decimal(0.1))) ])
def Binomial_pmf(k,n,p): ''' calculates the pmf of binomial distribution ''' k_decimal = Decimal(k) n_decimal = Decimal(n) p_decimal = Decimal(p) tmp = Decimal(gammaln(n+1)-gammaln(k+1)-gammaln(n-k+1))+Decimal(k_decimal*p_decimal.ln()+(n_decimal-k_decimal)*Decimal(1-p_decimal).ln()) return tmp.exp()
def _get_equivalent_order_volume_and_distance_weighted( self, orders: Set[LimitOrder]): current_price = self.strategy.get_price() return self._obtain_equivalent_weighted_order( orders, lambda o: Decimal.exp(-Decimal( str(abs(o.price - current_price) / current_price)) / self. _hanging_orders_cancel_pct))
def _get_equivalent_order_volume_and_age_weighted(self, orders: Set[LimitOrder]): max_order_age = getattr(self.strategy, "max_order_age", None) if max_order_age: return self._obtain_equivalent_weighted_order( orders, lambda o: Decimal.exp(-Decimal( str(self._limit_order_age(o) / max_order_age)))) return frozenset()
def interpolate_linear(logprob1, logprob2, weight1): """Performs linear interpolation of two probabilities. If a probability is so small that it will be rounded to zero, uses the decimal library. If a weight is zero, the corresponding log probability will be ignored. Otherwise if the log probability was ``-inf``, multiplication would result in a ``nan``. :type logprob1: logprob_type :param logprob1: logarithm of first input probability :type logprob2: logprob_type :param logprob2: logarithm of second input probability :type weight1: logprob_type :param weight1: interpolation weight for the first probability :rtype: logprob_type :returns: logarithm of the weighted sum of the input probabilities """ prob1 = numpy.exp(numpy.float64(logprob1)) prob2 = numpy.exp(numpy.float64(logprob2)) if (prob1 > 0) and (prob2 > 0): weight2 = 1.0 - weight1 prob = weight1 * prob1 prob += weight2 * prob2 return logprob_type(numpy.log(prob)) else: # An exp() resulted in an underflow (or -inf logprob). Use the decimal # library. getcontext().prec = 16 d_weight1 = Decimal(weight1) d_weight2 = Decimal(1.0) - d_weight1 d_logprob1 = Decimal(logprob1) d_logprob2 = Decimal(logprob2) d_zero = Decimal(0.0) d_prob = d_zero if d_weight1 != d_zero: d_prob += d_weight1 * d_logprob1.exp() if d_weight2 != d_zero: d_prob += d_weight2 * d_logprob2.exp() return logprob_type(d_prob.ln())
def DecimalOperation(): import decimal from decimal import Decimal, getcontext getcontext().prec = 100 getcontext().rounding = getattr(decimal, 'ROUND_HALF_EVEN') # default; other: FLOOR, CELILING, DOWN, ... getcontext().traps[decimal.FloatOperation] = True Decimal((0, (1, 4, 1, 4), -3)) # 1.414 a = Decimal(1 << 31) / Decimal(100000) print(round(a, 5)) # total digits print(a.quantize(Decimal("0.00000"))) # 21474.83648 print(a.sqrt(), a.ln(), a.log10(), a.exp(), a**2)
def exp(x_value): '''The exponetial function as a Vector function. **How to use** >>> x0 = 4 >>> x1 = (1, float(2), Decimal('3')) >>> exp(x0) Decimal('54.59815003314423907811026120') >>> x1 = (1, float(2), Decimal('3')) >>> exp(x1) Vector([2.718281828459045235360287471, 7.389056098930650227230427461, 20.08553692318766774092852965]) ''' return Decimal.exp(x_value)
def twr(begin_ts, ts, current_ts): """ Computes a Time Weighted Risk parcel. Normalizes the timestamps and returns the TWR parcel. Args: begin_ts: An int representing the beginning timestamp. ts: An int representing a specific timestamp. current_ts: An int representing the most recent timestamp. Returns: A Decimal from 0 to 0.5. """ begin_diff = ts - begin_ts diff = current_ts - begin_ts if diff == 0: normalized = 1 else: normalized = Decimal(begin_diff) / Decimal(diff) twr = 1 / (1 + Decimal.exp(Decimal(-12) * normalized + Decimal(2) + ((1 - Metrics.TIME_RANGE) * 10))) return twr
def delta_v(u, v): return Decimal(2)*(u*v*Decimal.exp(v) - Decimal(2)*Decimal.exp(-u)) * \ (u*Decimal.exp(v) - Decimal(2)*v*Decimal.exp(-u))
def delta_u(u, v): return Decimal(2)*(Decimal.exp(v) + Decimal(2)*v*Decimal.exp(-u)) * \ (u*Decimal.exp(v) - Decimal(2)*v*Decimal.exp(-u)) def delta_v(u, v): return Decimal(2)*(u*v*Decimal.exp(v) - Decimal(2)*Decimal.exp(-u)) * \ (u*Decimal.exp(v) - Decimal(2)*v*Decimal.exp(-u)) print 'gradient decent' eta = Decimal(0.1) # learning rate u = Decimal(1) # weight component v = Decimal(1) # weight component for i in range(1, 20): Ein = (u*Decimal.exp(v) - 2*v*Decimal.exp(-u))**2 print 'Error:', i, Ein if (Ein < 10**-14): print '({}, {})'.format(u, v) break temp_u = u - eta * delta_u(u, v) v = v - eta * delta_v(u, v) u = temp_u print 'coordinate decent' eta = Decimal(0.1) # learning rate u = Decimal(1) # weight component v = Decimal(1) # weight component for i in range(1, 15): temp_u = u - eta * delta_u(u, v) Ein_u = (temp_u*Decimal.exp(v) - 2*v*Decimal.exp(-temp_u))**2
def pochisq(x, df=255): """ Compute probability of χ² test value. Adapted from: Hill, I. D. and Pike, M. C. Algorithm 299 Collected Algorithms for the CACM 1967 p. 243 Updated for rounding errors based on remark in ACM TOMS June 1985, page 185. According to http://www.fourmilab.ch/random/: We interpret the percentage (return value*100) as the degree to which the sequence tested is suspected of being non-random. If the percentage is greater than 99% or less than 1%, the sequence is almost certainly not random. If the percentage is between 99% and 95% or between 1% and 5%, the sequence is suspect. Percentages between 90% and 95% and 5% and 10% indicate the sequence is “almost suspect”. Arguments: x: Obtained chi-square value. df: Degrees of freedom, defaults to 255 for random bytes. Returns: The degree to which the sequence tested is suspected of being non-random, as a Decimal. """ # Check arguments first if not isinstance(df, int): raise ValueError("df must be an integer") if x <= 0.0 or df < 1: return 1.0 # Constants LOG_SQRT_PI = Decimal("0.5723649429247000870717135") # log(√π) I_SQRT_PI = Decimal("0.5641895835477562869480795") # 1/√π BIGX = Decimal(20) a = Decimal(0.5) * x even = df % 2 == 0 if df > 1: y = -a.exp() nd = stat.NormalDist() s = y if even else Decimal(2) * Decimal(nd.cdf(float(-x.sqrt()))) if df > 2: x = 0.5 * (df - 1.0) z = Decimal(1) if even else Decimal(0.5) if a > BIGX: e = Decimal(0) if even else LOG_SQRT_PI c = a.ln() while z <= x: e = z.ln() + e s += (c * z - a - e).exp() z += Decimal(1) return s else: e = Decimal(1) if even else I_SQRT_PI / a.sqrt() c = Decimal(0) while z <= x: e = e * a / z c = c + e z += Decimal(1) return c * y + s else: return s
def compute_defect_probability(r_twr, f_twr, a_twr, r_weight, f_weight, a_weight): twr = r_twr * r_weight + f_twr * f_weight + a_twr * a_weight probability = 1 - Decimal.exp(-twr) return probability
def sigmoid(self, x): x = Decimal(x) return Decimal(1 / (1 + x.exp()))
getcontext().prec = 100 FIXED_1 = (1<<MAX_PRECISION) HiTerm = namedtuple('HiTerm','val,exp') LoTerm = namedtuple('LoTerm','num,den') hiTerms = [] loTerms = [] for n in range(LOG_NUM_OF_HI_TERMS+1): cur = Decimal(LOG_MAX_HI_TERM_VAL)/2**n val = int(FIXED_1*cur) exp = int(FIXED_1*cur.exp()) hiTerms.append(HiTerm(val,exp)) MAX_VAL = hiTerms[0].exp-1 loTerms = [LoTerm(FIXED_1*2,FIXED_1*2)] res = optimalLog(MAX_VAL,hiTerms,loTerms,FIXED_1) while True: n = len(loTerms) val = FIXED_1*(2*n+2) loTermsNext = loTerms+[LoTerm(val//(2*n+1),val)] resNext = optimalLog(MAX_VAL,hiTerms,loTermsNext,FIXED_1) if res < resNext: res = resNext loTerms = loTermsNext else:
def exp(value: Decimal) -> Decimal: """e to the power of value""" return value.exp()
def __call__(self, arg): return Decimal.exp(arg[0] + Decimal(3) * arg[1] - Decimal(0.1)) + \ Decimal.exp(arg[0] - Decimal(3) * arg[1] - Decimal(0.1)) + \ Decimal.exp(-arg[0] - Decimal(0.1))
def compute_defect_probability(r_twr, f_twr, a_twr, r_weight, f_weight, a_weight): twr = r_twr * r_weight + f_twr * f_weight + a_twr * a_weight probability = 1 - Decimal.exp(- twr) return probability
# we reach the limit of the float type # after 20 iterations, ie. n_20 = n_21 = n_22 = ... def taylor_e(): approx = 0 term = 1.0 k = 0 while True: approx += term yield approx k += 1 term /= k dec_e = Decimal.exp(Decimal(1.0)) ## the same, but using the decimal library ## here we get stuck after 26 iterations def taylor_dec_e(): approx = Decimal(0) term = Decimal(1) k = 0 while True: approx += term yield approx diff = abs(approx - dec_e) digits = math.floor(-Decimal.log10(diff)) print(f"diff after {k} iters = {digits}") print(approx)
x % y # returns 1 divmod(x, y) # returns (3, 1) (x == y* (x // y) + x % y) # returns True x = Decimal(-10) y = Decimal(3) x//y # returns -3 #here trunc(x//y) happens instead of math.floor(x//y) like in the case of integers x % y # returns -1 c, d = divmod(x, y) # returns (3, 1) (x == y* (x // y) + x % y) # returns True #logarithmic, exponent and square root is implemented differntly by Decimal as compared to math a = Decimal('1.5') a.ln() a.exp() a.sqrt() #Note: If we use math module, it first converts the Decimal type to float and then performs the mathematical operation. math.sqrt(a) == a.sqrt() # return False #BOOLEANS -- >they are integer subclass True --> 1, False -->0, However they don't share the memory address issubclass(bool, int) # returns True isinstance(True, bool) # returns True isinstance(True, int) # returns True int(True) # returns 1 int(False) #returns 0 True is 1 # returns False
def decimal_power(num, exp): return decimal_truncate(Decimal.exp(Decimal.ln(num) * exp))
def wmh_index(sep_dist, dist_p, num_points, dim, approx=None, full_output=False): """Quality index of Wahl, Mercadier, and Helbert. In [Wahl2017]_, the idea to use the probability to obtain a sample with a separation distance less or equal to `sep_dist` was presented. As the exact value is unknown, it has to be approximated. Let the probability be :math:`1 - 10^{x}`, then this function computes :math:`x`. This value should be minimized. The worst possible value is zero. The :mod:`decimal` library is used internally to obtain a higher precision than conventional floating point arithmetic. Parameters ---------- sep_dist : float The measured separation distance. dist_p : int The `p` of the used :math:`L_p` distance. num_points : int The number of points in the sample. dim : int The dimension of the sampled space. approx : sequence, optional A sequence of approximation methods to use. Default is ("polynomials", "gauss", "gumbel", "weibull"), which are the four methods presented in [Wahl2017]_. full_output : bool, optional If true, a list of approximation values is returned. Else, the maximum of the used approximations (the most conservative estimate) is returned. Returns ------- approximations : float or list The maximum of the calculated approximations or the whole list of them (according to the order in `approx`), depending on the switch `full_output`. References ---------- .. [Wahl2017] François Wahl, Cécile Mercadier, Céline Helbert (2017). A standardized distance-based index to assess the quality of space-filling designs. Statistics and Computing, Volume 27, Issue 2, pp 319–329. https://dx.doi.org/10.1007/s11222-015-9624-z """ def a(l, p, d): ret_value = math.gamma(1.0 / p) ** (2 * d - l) ret_value *= math.gamma(2.0 / p) ** (l - d) ret_value /= math.gamma(float(l) / p + 1.0) ret_value *= (-1) ** (l - d) * binom_coeff(d, l - d) * (2.0 / p) ** d return ret_value def G(t, p, d): """C.d.f. of the distance of two random uniform points.""" if math.isinf(p): return (2.0 * t - t ** 2) ** d if t <= 1.0 else 1.0 summands = [] for i in range(d, 2 * d + 1): if t >= 0.0 and t <= 1.0: summands.append(a(i, p, d) * t ** i) return math.fsum(summands) def mean(p): return 2.0 / ((p + 1) * (p + 2)) assert sep_dist >= 0.0 assert dist_p > 0 assert num_points >= 0 assert dim >= 1 if num_points < 2: return 0.0 if approx is None: approx = ("polynomials", "gauss", "gumbel", "weibull") one = Decimal(1.0) two = Decimal(2.0) nc2 = Decimal(binom_coeff(num_points, 2)) approximations = [] for app in approx: if app == "polynomials": if sep_dist <= 1.0: g_value = Decimal(G(sep_dist, dist_p, dim)) approximations.append(((one - g_value) ** nc2).log10()) else: approximations.append(float("-inf")) elif app == "gauss": assert not math.isinf(dist_p) var = mean(2 * dist_p) - mean(dist_p) ** 2 x = sep_dist ** dist_p - dim * mean(dist_p) x /= math.sqrt(dim * var) cdf_value = Decimal((1.0 + math.erf(x / math.sqrt(2.0))) * 0.5) approximations.append(((one - cdf_value) ** nc2).log10()) elif app == "weibull": assert not math.isinf(dist_p) temp = Decimal(-a(dim, dist_p, dim)) * nc2 * Decimal(sep_dist ** dim) approximations.append(temp.exp().log10()) elif app == "gumbel": assert not math.isinf(dist_p) x = sep_dist ** dist_p - dim * mean(dist_p) x /= math.sqrt(dim * var) x = Decimal(x) alpha = (two * nc2.ln()).sqrt() beta = nc2.ln().ln() + Decimal(4.0 * math.pi).ln() beta /= two * alpha beta -= alpha approximations.append((-(alpha * (x - beta)).exp()).exp().log10()) else: raise ValueError("Unknown approximation method: " + str(app)) approximations = [float(app) for app in approximations] if full_output: return approximations else: return max(approximations)
def delta_u(u, v): return Decimal(2)*(Decimal.exp(v) + Decimal(2)*v*Decimal.exp(-u)) * \ (u*Decimal.exp(v) - Decimal(2)*v*Decimal.exp(-u))
def exp(n: D): return n.exp()
print(x == y * (x // y) + (x % y)) # true x = -10 y = 3 print(x // y, x % y) # -4 2 print(x == y * (x // y) + (x % y)) # true x = Decimal(-10) y = Decimal(3) print(x // y, x % y) # -3 -1 print(x == y * (x // y) + (x % y)) # true ## other math functions a = Decimal("0.1") print(a.ln()) print(a.exp()) print(a.sqrt()) print(math.sqrt(a)) ### differences x = 2 x_dec = Decimal(2) root_float = math.sqrt(x) root_mixed = math.sqrt(x_dec) root_dec = x_dec.sqrt() print(format(root_float, "1.27f")) print(format(root_mixed, "1.27f")) print(format(root_dec))
a = Decimal('-10') b = Decimal('3') print(a // b, a % b) print(divmod(a, b)) print(a == b * (a // b) + a % b) # On the other hand, we see that in this case the // and % operators did not result in the same values, although the equation was satisfied in both instances. # #### Other Mathematical Functions # The Decimal class implements a variety of mathematical functions. a = Decimal('1.5') print(a.log10()) # base 10 logarithm print(a.ln()) # natural logarithm (base e) print(a.exp()) # e**a print(a.sqrt()) # square root # Although you can use the math function of the math module, be aware that the math module functions will cast the Decimal numbers to floats when it performs the various operations. So, if the precision is important (which it probably is if you decided to use Decimal numbers in the first place), choose the math functions of the Decimal class over those of the math module. x = 2 x_dec = Decimal(2) import math root_float = math.sqrt(x) root_mixed = math.sqrt(x_dec) root_dec = x_dec.sqrt() print(format(root_float, '1.27f')) print(format(root_mixed, '1.27f')) print(root_dec)
# Ejercicio 755: Calcular la raíz cuadrada y el exponente de un objeto Decimal. from decimal import Decimal numero = Decimal(1.79) raiz = numero.sqrt() exp = numero.exp() print(raiz) print(exp)
def __init__(self, f, g, start, end, iv): self.f = f self.g = g self.start = start self.end = end self.iv = iv def approximate(self, inc): curY = self.iv curT = self.start while curT <= self.end: gEval = self.g(curT) print(f"y({curT}) = {curY}; Φ({curT}) = {gEval}; Difference: {gEval - curY}") curY = curY + self.f(curT, curY) * (inc) curT += inc ranges = [Decimal(i) for i in (".1", ".05", ".025")] print("For y' = 3 + t - y") f = lambda t, y: 3 + t - y g = lambda t: t + Decimal('2') - (-t).exp() for r in ranges: print("Increment of", r) EulerMethod(f, g, Decimal('0'), Decimal('0.4'), Decimal('1')).approximate(r) print("\nFor y' = 0.5 - t + 2y") f = lambda t, y: Decimal('0.5') - t + 2 * y g = lambda t: Decimal('0.5') * t + Decimal.exp(2 * t) for r in ranges: print("Increment of", r) EulerMethod(f, g, Decimal('0'), Decimal('0.4'), Decimal('1')).approximate(r)