def adjust_ret_list(retlist): retlist[0].cdf_low="0.0" retlist[-1].cdf_up="1.0" with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: min_value=gmpy2.exp10(-digits_for_input_cdf) current=min_value for pbox in retlist: with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: if gmpy2.is_zero(gmpy2.mpfr(pbox.cdf_low)) or gmpy2.mpfr(pbox.cdf_low)<current: pbox.cdf_low=round_number_down_to_digits(current, digits_for_input_cdf) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: current=current+min_value if gmpy2.is_zero(gmpy2.mpfr(pbox.cdf_up)) or gmpy2.mpfr(pbox.cdf_up)<current: pbox.cdf_up=round_number_down_to_digits(current, digits_for_input_cdf) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: current=gmpy2.sub(gmpy2.mpfr("1.0"), min_value) for pbox in retlist[::-1]: with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: if gmpy2.mpfr(pbox.cdf_up)==gmpy2.mpfr("1.0") or gmpy2.mpfr(pbox.cdf_up)>current: pbox.cdf_up=round_number_up_to_digits(current, digits_for_input_cdf) current=gmpy2.sub(current, min_value) if gmpy2.mpfr(pbox.cdf_low)==gmpy2.mpfr("1.0") or gmpy2.mpfr(pbox.cdf_low)>current: pbox.cdf_low=round_number_up_to_digits(current, digits_for_input_cdf) retlist[0].cdf_low = "0.0" retlist[-1].cdf_up = "1.0" return retlist
def subtraction(self, interval): reset_default_precision() res_inc_left = False res_inc_right = False if self.include_lower and interval.include_lower: res_inc_left = True if self.include_upper and interval.include_upper: res_inc_right = True with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: res_left = gmpy2.sub(mpfr(self.lower), mpfr(interval.upper)) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: res_right = gmpy2.sub(mpfr(self.upper), mpfr(interval.lower)) if res_left <= res_right: res_right = round_number_up_to_digits(res_right, self.digits) res_left = round_number_down_to_digits(res_left, self.digits) return Interval(res_left, res_right, res_inc_left, res_inc_right, self.digits) else: res_right = round_number_down_to_digits(res_right, self.digits) res_left = round_number_up_to_digits(res_left, self.digits) return Interval(res_right, res_left, res_inc_right, res_inc_left, self.digits)
def find_min_abs_interval(interval): with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundToZero, precision=mpfr_proxy_precision) as ctx: left = abs(mpfr(interval.lower)) right = abs(mpfr(interval.upper)) if left < right: #Now the number is positive so we can round down return round_number_down_to_digits(left, digits_for_range) else: #Now the number is positive so we can round down return round_number_down_to_digits(right, digits_for_range)
def createDSIfromDistribution(distribution, n=50): #np.logspace(-9, 5, base=2, num=50) spacing should be done by powers of 2 if distribution.range_()[0]==0.0 and distribution.range_()[-1]==1.0 and use_powers_of_two_spacing: lin_space = powers_of_two_spacing() elif "FTE" in distribution.name and use_powers_of_two_spacing: lin_space = powers_of_two_error(distribution.d.precision) else: lin_space = np.linspace(distribution.range_()[0], distribution.range_()[-1], num=n + 1, endpoint=True) if custom_spacing: try: lin_space = distribution.get_my_spacing() except: lin_space = np.linspace(distribution.range_()[0], distribution.range_()[-1], num=n + 1, endpoint=True) cdf_distr=distribution.get_piecewise_cdf() ret_list=[] for i in range(0, len(lin_space)-1): with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: lower=round_number_down_to_digits(gmpy2.mpfr(lin_space[i]), digits_for_input_discretization) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: upper=round_number_up_to_digits(gmpy2.mpfr(lin_space[i+1]), digits_for_input_discretization) cdf_low_bound=min(1.0, max(0.0, cdf_distr(float(lin_space[i])))) cdf_up_bound=min(1.0, max(0.0, cdf_distr(float(lin_space[i+1])))) cdf_low_string=dec2Str(round_near(cdf_low_bound, digits_for_input_cdf)) cdf_up_string=dec2Str(round_near(cdf_up_bound, digits_for_input_cdf)) pbox = PBox(Interval(lower, upper, True, False, digits_for_range), cdf_low_string, cdf_up_string) ret_list.append(pbox) ret_list=adjust_ret_list(ret_list) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: ret_list[0].interval.lower = \ round_number_down_to_digits(gmpy2.mpfr(distribution.a_real), digits_for_input_discretization) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: ret_list[-1].interval.upper = \ round_number_up_to_digits(gmpy2.mpfr(distribution.b_real), digits_for_input_discretization) ret_list[-1].interval.include_upper = True mixarith=MixedArithmetic(ret_list[0].interval.lower,ret_list[-1].interval.upper,ret_list) return mixarith
def compute_interval(self): with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: res_left = gmpy2.sub(mpfr(self.center.lower), mpfr(self.add_all_coefficients_lower_abs())) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: res_right = gmpy2.add(mpfr(self.center.upper), mpfr(self.add_all_coefficients_upper_abs())) if res_left <= res_right: return Interval( round_number_down_to_digits(res_left, digits_for_range), round_number_up_to_digits(res_right, digits_for_range), True, True, digits_for_range) else: return Interval( round_number_down_to_digits(res_right, digits_for_range), round_number_up_to_digits(res_left, digits_for_range), True, True, digits_for_range)
def round_value_to_interval(str_value): with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: res_left = mpfr(str_value) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: res_right = mpfr(str_value) return Interval( round_number_down_to_digits(res_left, digits_for_range), round_number_up_to_digits(res_right, digits_for_range), True, True, digits_for_range)
def compute_middle_point_given_interval(low, upper): with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: res_left = gmpy2.add(gmpy2.div(mpfr(upper), mpfr("2.0")), gmpy2.div(mpfr(low), mpfr("2.0"))) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: res_right = gmpy2.add(gmpy2.div(mpfr(upper), mpfr("2.0")), gmpy2.div(mpfr(low), mpfr("2.0"))) return Interval( round_number_down_to_digits(res_left, digits_for_range), round_number_up_to_digits(res_right, digits_for_range), True, True, digits_for_range)
def compute_uncertainty_given_interval(low, upper): coefficients = {} with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: res_left = gmpy2.sub(gmpy2.div(mpfr(upper), mpfr("2.0")), gmpy2.div(mpfr(low), mpfr("2.0"))) with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: res_right = gmpy2.sub(gmpy2.div(mpfr(upper), mpfr("2.0")), gmpy2.div(mpfr(low), mpfr("2.0"))) coefficients[AffineManager.get_new_error_index()]=\ Interval(round_number_down_to_digits(res_left, digits_for_range), round_number_up_to_digits(res_right, digits_for_range), True, True, digits_for_range) return coefficients
def division(self, interval): reset_default_precision() tmp_res_left = [] tmp_res_right = [] with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: new_right_lower = gmpy2.div(1.0, mpfr(interval.upper)) new_right_upper = gmpy2.div(1.0, mpfr(interval.lower)) tmp_res_left.append( gmpy2.mul(mpfr(self.lower), mpfr(new_right_lower))) tmp_res_left.append( gmpy2.mul(mpfr(self.lower), mpfr(new_right_upper))) tmp_res_left.append( gmpy2.mul(mpfr(self.upper), mpfr(new_right_lower))) tmp_res_left.append( gmpy2.mul(mpfr(self.upper), mpfr(new_right_upper))) min_index = [ i for i, value in enumerate(tmp_res_left) if value == min(tmp_res_left) ] with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: new_right_lower = gmpy2.div(1.0, mpfr(interval.upper)) new_right_upper = gmpy2.div(1.0, mpfr(interval.lower)) tmp_res_right.append( gmpy2.mul(mpfr(self.lower), mpfr(new_right_lower))) tmp_res_right.append( gmpy2.mul(mpfr(self.lower), mpfr(new_right_upper))) tmp_res_right.append( gmpy2.mul(mpfr(self.upper), mpfr(new_right_lower))) tmp_res_right.append( gmpy2.mul(mpfr(self.upper), mpfr(new_right_upper))) max_index = [ i for i, value in enumerate(tmp_res_right) if value == max(tmp_res_right) ] # We have to swap the boundaries here 1/[1,2]=[.5, 1] new_right_lower_inc = interval.include_upper new_right_upper_inc = interval.include_lower tmp_bounds = [ self.include_lower * new_right_lower_inc, self.include_lower * new_right_upper_inc, self.include_upper * new_right_lower_inc, self.include_upper * new_right_upper_inc ] res_inc_left = any([tmp_bounds[index] for index in min_index]) res_inc_right = any([tmp_bounds[index] for index in max_index]) res_left = round_number_down_to_digits(tmp_res_left[min_index[0]], self.digits) res_right = round_number_up_to_digits(tmp_res_right[max_index[0]], self.digits) return Interval(res_left, res_right, res_inc_left, res_inc_right, self.digits)
def multiplication(self, interval): reset_default_precision() tmp_res_left = [] tmp_res_right = [] zero_is_included = self.check_zero_is_in_interval( ) or interval.check_zero_is_in_interval() with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundDown, precision=mpfr_proxy_precision) as ctx: tmp_res_left.append( gmpy2.mul(mpfr(self.lower), mpfr(interval.lower))) tmp_res_left.append( gmpy2.mul(mpfr(self.lower), mpfr(interval.upper))) tmp_res_left.append( gmpy2.mul(mpfr(self.upper), mpfr(interval.lower))) tmp_res_left.append( gmpy2.mul(mpfr(self.upper), mpfr(interval.upper))) min_index = [ i for i, value in enumerate(tmp_res_left) if value == min(tmp_res_left) ] with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundUp, precision=mpfr_proxy_precision) as ctx: tmp_res_right.append( gmpy2.mul(mpfr(self.lower), mpfr(interval.lower))) tmp_res_right.append( gmpy2.mul(mpfr(self.lower), mpfr(interval.upper))) tmp_res_right.append( gmpy2.mul(mpfr(self.upper), mpfr(interval.lower))) tmp_res_right.append( gmpy2.mul(mpfr(self.upper), mpfr(interval.upper))) max_index = [ i for i, value in enumerate(tmp_res_right) if value == max(tmp_res_right) ] tmp_bounds = [ self.include_lower * interval.include_lower, self.include_lower * interval.include_upper, self.include_upper * interval.include_lower, self.include_upper * interval.include_upper ] res_inc_left = any([tmp_bounds[index] for index in min_index]) res_inc_right = any([tmp_bounds[index] for index in max_index]) min_value = tmp_res_left[min_index[0]] max_value = tmp_res_right[max_index[0]] if gmpy2.is_zero(min_value) and zero_is_included: res_inc_left = True if gmpy2.is_zero(max_value) and zero_is_included: res_inc_right = True res_left = round_number_down_to_digits(min_value, self.digits) res_right = round_number_up_to_digits(max_value, self.digits) return Interval(res_left, res_right, res_inc_left, res_inc_right, self.digits)