Beispiel #1
0
    def elaborate_Gelpia_error_intervals(self, constraints, symbolic_affine):
        results = {}
        logging_constraints = []
        prob = constraints_probabilities

        #constraint_dict = {}
        #for constraint in constraints:
        #    values=constraints[constraint][prob]
        #    constraint_dict[str(constraint)]=[values[0], values[1]]

        second_order_lower, second_order_upper = \
            SymbolicToGelpia(symbolic_affine.center, symbolic_affine.variables, constraints=constraints). \
                compute_concrete_bounds(debug=True, zero_output_epsilon=True)
        center_interval = Interval(second_order_lower, second_order_upper,
                                   True, True, digits_for_range)

        #concrete_symbolic_interval = symbolic_affine.compute_interval_error(center_interval)
        #results["1"] = Interval(str(concrete_symbolic_interval.lower),
        #                        str(concrete_symbolic_interval.upper),
        #                        True,True,digits_for_range)

        print("Error for prob: " + str(prob))

        logging_constraints.append((prob, constraints))
        constraints_interval = symbolic_affine.compute_interval_error(
            center_interval, constraints=constraints)
        results[str(prob)] = Interval(str(constraints_interval.lower),
                                      str(constraints_interval.upper), True,
                                      True, digits_for_range)
        return results, logging_constraints
Beispiel #2
0
 def subtraction(self, affine):
     new_center = self.center.subtraction(affine.center)
     new_coefficients = {}
     keys = set().union(self.coefficients, affine.coefficients)
     for key in keys:
         res_int = self.coefficients.get(key, Interval("0","0", True, True, digits_for_range))\
             .subtraction(affine.coefficients.get(key, Interval("0","0", True, True, digits_for_range)))
         new_coefficients[key] = res_int
     return AffineInstance(new_center, new_coefficients)
 def check_expression_is_constant_zero(expression):
     try:
         interval = Interval(expression.value, expression.value, True, True,
                             digits_for_range)
         return check_interval_is_zero(interval)
     except:
         return False
     return False
Beispiel #4
0
 def do_quantize(self, left_node, operator, right_node):
     if (operator=="+" or operator=="-") and \
             check_interval_is_zero(
                 Interval(left_node.discretization.intervals[0].interval.lower,
                          left_node.discretization.intervals[-1].interval.upper,
                          True, True, digits_for_range)):
         return False
     return True
 def compute_interval(self):
     self_coefficients = self.add_all_coefficients_abs_exact()
     lower_expr = self.center.subtraction(self_coefficients)
     upper_expr = self.center.addition(self_coefficients)
     lower_concrete, _ = SymbolicToGelpia(
         lower_expr, self.variables).compute_concrete_bounds()
     _, upper_concrete = SymbolicToGelpia(
         upper_expr, self.variables).compute_concrete_bounds()
     return Interval(lower_concrete, upper_concrete, True, True,
                     digits_for_range)
Beispiel #6
0
 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)
Beispiel #7
0
 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)
Beispiel #8
0
 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_interval_error(self, center_interval, constraints=None):
     tmp_variables = copy.deepcopy(self.variables)
     memorize_eps = Interval("-1.0", "1.0", True, True, digits_for_range)
     for var in tmp_variables:
         # for the moment there should be one
         if "eps" in var:
             memorize_eps = Interval(tmp_variables[var][0],
                                     tmp_variables[var][1], True, True,
                                     digits_for_range)
             tmp_variables[var] = ["-1.0", "1.0"]
             break
     self_coefficients = self.add_all_coefficients_abs_exact()
     _, coeff_upper = SymbolicToGelpia(self_coefficients, tmp_variables,
                                       constraints).compute_concrete_bounds(
                                           debug=True,
                                           zero_output_epsilon=True)
     coeff_interval=Interval("-"+coeff_upper,coeff_upper,True,True,digits_for_range).\
                         perform_interval_operation("*", memorize_eps)
     lower_concrete = center_interval.perform_interval_operation(
         "-", coeff_interval)
     upper_concrete = center_interval.perform_interval_operation(
         "+", coeff_interval)
     return Interval(lower_concrete.lower, upper_concrete.upper, True, True,
                     digits_for_range)
Beispiel #10
0
 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
Beispiel #11
0
 def compute_non_linearity(self):
     #tmp_variables=copy.deepcopy(self.variables)
     #memorize_eps=Interval("-1.0","1.0",True,True,digits_for_range)
     #for var in tmp_variables:
     #    # for the moment there should be one
     #    if "eps" in var:
     #        memorize_eps=Interval(tmp_variables[var][0], tmp_variables[var][1], True, True, digits_for_range)
     #        tmp_variables[var]=["-1.0","1.0"]
     #        break
     _, coeff_upper = SymbolicToGelpia(
         self.expression, self.variables,
         self.constraints).compute_concrete_bounds(debug=True,
                                                   zero_output_epsilon=True)
     interval = Interval("-" + coeff_upper, coeff_upper, True, True,
                         digits_for_range)
     #lower_concrete=center_interval.perform_interval_operation("-", coeff_interval)
     #upper_concrete=center_interval.perform_interval_operation("+", coeff_interval)
     return interval
Beispiel #12
0
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
Beispiel #13
0
    def precise_create_exp_for_Gelpia(exact, error,
                                      real_precision_constraints):

        second_order_lower, second_order_upper = \
            SymbolicToGelpia(error.center, error.variables, real_precision_constraints). \
                compute_concrete_bounds(debug=True, zero_output_epsilon=True)
        center_interval = Interval(second_order_lower, second_order_upper,
                                   True, True, digits_for_range)
        err_interval = error.compute_interval_error(
            center_interval, constraints=real_precision_constraints)

        new_exact = copy.deepcopy(exact)
        if not check_interval_is_zero(err_interval):
            err_expression = SymbolicAffineManager.from_Interval_to_Expression(
                err_interval)
            new_exact = new_exact.add_constant_expression(err_expression)
            #The exact form has only a center (no error terms)
        encoding = "(" + GELPHIA_exponent_function_name + "(" + str(
            new_exact.center) + "))"
        return SymbolicAffineInstance(SymExpression(encoding), {},
                                      copy.deepcopy(exact.variables))
Beispiel #14
0
    def create_discretization(self):
        lower = self.wrapperInputDistribution.discretization.intervals[
            0].interval.lower
        upper = self.wrapperInputDistribution.discretization.intervals[
            -1].interval.upper
        with gmpy2.local_context(
                set_context_precision(self.precision, self.exp),
                round=(gmpy2.RoundDown if not round_constants_to_nearest else
                       gmpy2.RoundToNearest)) as ctx:
            lower = round_number_down_to_digits(mpfr(lower), digits_for_range)

        with gmpy2.local_context(
                set_context_precision(self.precision, self.exp),
                round=(gmpy2.RoundUp if not round_constants_to_nearest else
                       gmpy2.RoundToNearest)) as ctx:
            upper = round_number_up_to_digits(mpfr(upper), digits_for_range)
        #The following somehow remind of a dirac distribution.
        return MixedArithmetic(lower, upper, [
            PBox(Interval(lower, upper, True, True, digits_for_range), "0.0",
                 "1.0")
        ])
Beispiel #15
0
    def multiplication(self, affine, recursion_limit_for_pruning, dReal):
        new_center = self.center.multiplication(affine.center)
        new_coefficients = {}
        keys = set().union(self.coefficients, affine.coefficients)
        for key in keys:
            second_term = affine.center.multiplication(
                self.coefficients.get(
                    key, Interval("0", "0", True, True, digits_for_range)))
            first_term = self.center.multiplication(
                affine.coefficients.get(
                    key, Interval("0", "0", True, True, digits_for_range)))
            res = first_term.addition(second_term)
            new_coefficients[key] = res
        self_non_linear = Interval(self.add_all_coefficients_lower_abs(),
                                   self.add_all_coefficients_upper_abs(), True,
                                   True, digits_for_range)
        affine_non_linear = Interval(affine.add_all_coefficients_lower_abs(),
                                     affine.add_all_coefficients_upper_abs(),
                                     True, True, digits_for_range)
        res = self_non_linear.multiplication(affine_non_linear)

        value = find_max_abs_interval(res)  #This MUST positive
        negative_value = "-" + value
        interval_value = Interval(negative_value, value, True, True,
                                  digits_for_range)
        if not check_interval_is_zero(interval_value):
            low_value, up_value = clean_non_linearity_affine(
                self.coefficients, affine.coefficients, interval_value,
                recursion_limit_for_pruning, dReal)
            middle_point_non_linear = AffineManager.compute_middle_point_given_interval(
                low_value, up_value)
            uncertainty_non_linear = AffineManager.compute_uncertainty_given_interval(
                low_value, up_value)
            new_center = new_center.addition(middle_point_non_linear)
            new_coefficients.update(uncertainty_non_linear)
        return AffineInstance(new_center, new_coefficients)
Beispiel #16
0
 def sum_cdfs(self, pbox):
     tmp=Interval(self.cdf_low, self.cdf_up, True, True)\
         .addition(Interval(pbox.cdf_low, pbox.cdf_up, True, True))
     return PBox(None, tmp.lower, tmp.upper)
Beispiel #17
0
def from_DSI_to_PBox(edges_lower, values_lower, edges_upper, values_upper):
    edges_lower=convertListToDecimals(edges_lower)
    values_lower=convertListToDecimals(values_lower)
    edges_upper=convertListToDecimals(edges_upper)
    values_upper=convertListToDecimals(values_upper)

    #plot_operation(edges_lower,values_lower,values_upper)

    ret_list=[]
    if not edges_lower==edges_upper:
        print("Lists should be identical")
        exit(-1)

    pair_values_lower=createPairsFromBounds(values_lower)
    pair_values_upper=createPairsFromBounds(values_upper)

    for pair_value_upper in pair_values_upper:
        index = bisect.bisect_left(values_lower, pair_value_upper[0])
        pair_value_upper[1] = True

        #in case we go out of bounds we take the last one
        if index==len(values_lower):
            index=index-1

        #the lower bound of the forward box is the one before the current box
        lower_index=pair_value_upper[2]
        if lower_index==0:
            ret_list.append(PBox(Interval(dec2Str(edges_lower[lower_index]), dec2Str(edges_lower[index]),
                                          True, False, digits_for_range), "", dec2Str(pair_value_upper[0])))
        else:
            lower_index=lower_index-1
            ret_list.append(PBox(Interval(dec2Str(edges_lower[lower_index]), dec2Str(edges_lower[index]),
                                          False, False, digits_for_range), "", dec2Str(pair_value_upper[0])))

    for pair_value_lower in pair_values_lower:
        index = bisect.bisect_left(values_upper, pair_value_lower[0])
        pair_value_lower[1] = True
        if index==len(values_upper):
            index=index-1
        if index==pair_value_lower[2]:
            index=index-1
            ret_list.append(PBox(Interval(dec2Str(edges_lower[index]), dec2Str(edges_lower[pair_value_lower[2]]),
                                          False, False, digits_for_range), "", dec2Str(pair_value_lower[0])))
            continue
        if index>0:
            index = index - 1
            ret_list.append(PBox(Interval(dec2Str(edges_lower[index]), dec2Str(edges_lower[pair_value_lower[2]]),
                                          False, False, digits_for_range), "", dec2Str(pair_value_lower[0])))
            continue
        ret_list.append(PBox(Interval(dec2Str(edges_lower[index]), dec2Str(edges_lower[pair_value_lower[2]]),
                                      True, False, digits_for_range), "", dec2Str(pair_value_lower[0])))
    #sort by cdf, in case they are equal sort by lower bound
    ret_list.sort(key=lambda x: (float(x.cdf_up), float(x.interval.lower)))
    prec="0.0"
    done=False
    for elem in ret_list:
        if (not Decimal(prec)>=Decimal(elem.cdf_up)) and (not done):
            elem.cdf_low=prec
            prec=elem.cdf_up
        else:
            elem.cdf_low="REMOVE"
        if elem.cdf_up=="1.0":
            done=True
    #remove useless
    ret_list= [x for x in ret_list if not x.cdf_low=="REMOVE"]
    ret_list[-1].interval.include_upper=True

    #plot_operation(edges_lower,values_lower,values_upper)
    #plot_boxing(ret_list)

    sum=0
    for box in ret_list:
        sum=sum+Decimal(box.cdf_up)-Decimal(box.cdf_low)
    print("Check PDF from bounds to intervals: "+str(sum))
    return ret_list
Beispiel #18
0
    def compute_error_affine_form(self):
        if self.operator == "+":
            self.affine_error = self.leftoperand.affine_error.perform_affine_operation\
                ("+",self.rightoperand.affine_error)
        elif self.operator == "-":
            self.affine_error = self.leftoperand.affine_error.perform_affine_operation \
                ("-", self.rightoperand.affine_error)
        elif self.operator == "*":
            x_erry = self.exact_affines_forms[0].\
                perform_affine_operation("*", self.rightoperand.affine_error,
                                         recursion_limit_for_pruning=recursion_limit_for_pruning_error, dReal=False)
            y_errx=self.exact_affines_forms[1].\
                perform_affine_operation("*", self.leftoperand.affine_error,
                                         recursion_limit_for_pruning=recursion_limit_for_pruning_error, dReal=False)
            errx_erry=self.leftoperand.affine_error.\
                perform_affine_operation("*", self.rightoperand.affine_error,
                                         recursion_limit_for_pruning=recursion_limit_for_pruning_error, dReal=False)
            self.affine_error = x_erry.perform_affine_operation(
                "+", y_errx.perform_affine_operation("+", errx_erry))
        elif self.operator == "/":
            #val a = Interval.minAbs(rightInterval)
            #val errorMultiplier: Rational = -one / (a * a)

            total_affine_right = self.exact_affines_forms[1].\
                perform_affine_operation("+", self.rightoperand.affine_error,
                                         recursion_limit_for_pruning=recursion_limit_for_pruning_error, dReal=False)
            total_interval_right = total_affine_right.compute_interval()
            if check_zero_is_in_interval(total_interval_right):
                print("Potential division by zero!")
                exit(-1)

            min_abs_string = find_min_abs_interval(total_interval_right)
            multiplier_interval = Interval(
                "-1.0", "-1.0", True, True,
                digits_for_range).perform_interval_operation(
                    "/",
                    Interval(min_abs_string, min_abs_string, True, True,
                             digits_for_range).perform_interval_operation(
                                 "*",
                                 Interval(min_abs_string, min_abs_string, True,
                                          True, digits_for_range)))
            multiplier_affine = AffineInstance(multiplier_interval, {})
            inv_erry = multiplier_affine.perform_affine_operation(
                "*", self.rightoperand.affine_error)

            x_err_one_over_y=self.exact_affines_forms[0].\
                perform_affine_operation("*", inv_erry,
                                         recursion_limit_for_pruning=recursion_limit_for_pruning_error, dReal=False)
            one_over_y = self.exact_affines_forms[1].inverse()

            one_over_y_err_x = one_over_y.perform_affine_operation(
                "*",
                self.leftoperand.affine_error,
                recursion_limit_for_pruning=recursion_limit_for_pruning_error,
                dReal=False)

            errx_err_one_over_y = self.leftoperand.affine_error.\
                perform_affine_operation("*", inv_erry,
                                         recursion_limit_for_pruning=recursion_limit_for_pruning_error, dReal=False)

            self.affine_error = x_err_one_over_y.perform_affine_operation(
                "+",
                one_over_y_err_x.perform_affine_operation(
                    "+", errx_err_one_over_y))

        elif self.operator == "*+":
            self.affine_error = self.leftoperand.affine_error.\
                perform_affine_operation("+",
                        self.exact_affines_forms[0].perform_affine_operation("+", self.leftoperand.affine_error).
                        perform_affine_operation("*",self.rightoperand.discretization.affine))
        else:
            print("Operation not supported!")
            exit(-1)
Beispiel #19
0
def clean_co_domain(pbox,
                    smt_manager,
                    expression_center,
                    divisions_SMT,
                    valid_for_exit_pruning,
                    recursion_limit_for_pruning,
                    start_recursion_limit=0,
                    dReal=True):
    low, sup, inc_low, inc_sup = pbox.lower, pbox.upper, pbox.include_lower, pbox.include_upper
    if Decimal(low) == Decimal(sup):
        return pbox

    codomain_intervals = linear_space_with_decimals(low, sup, inc_low, inc_sup,
                                                    divisions_SMT)

    if len(codomain_intervals) == 0:
        return pbox

    exists_true = 0
    unknown_counter = 0

    for interval in codomain_intervals:
        tmp_pbox = SMT_Interface.PBoxSolver(interval[0][0], interval[1][0],
                                            interval[0][1], interval[1][1])
        smt_manager.set_expression_central(expression_center, tmp_pbox)
        smt_check = smt_manager.check(debug=False, dReal=dReal)
        if not smt_check:
            if exists_true >= 1:
                break
        else:
            if smt_check > 1:
                unknown_counter = unknown_counter + 1
            interval[2] = True
            exists_true = exists_true + 1

    if len(codomain_intervals) < divisions_SMT:
        exists_true = valid_for_exit_pruning + 1

    double_check = False
    for interval in codomain_intervals:
        if interval[2]:
            double_check = True
            break

    if not double_check:
        smt_manager.operation_center = ()
        print("Problem with cleaning. Z3:" +
              str(smt_manager.check(debug=False, dReal=False)) + ", dReal:" +
              str(smt_manager.check(debug=False, dReal=True)))
        ret_box = Interval(low, sup, inc_low, inc_sup, digits_for_range)
        return ret_box

    for ind, interval in enumerate(codomain_intervals[:-1]):
        if not interval[2]:
            low = dec2Str(codomain_intervals[ind + 1][0][0])
            inc_low = codomain_intervals[ind + 1][0][1]
        else:
            break
    reversed_codomain = codomain_intervals[::-1]
    for ind, interval in enumerate(reversed_codomain[:-1]):
        if not interval[2]:
            sup = dec2Str(reversed_codomain[ind + 1][1][0])
            inc_sup = reversed_codomain[ind + 1][1][1]
        else:
            break

    ret_box = Interval(low, sup, inc_low, inc_sup, digits_for_range)

    if start_recursion_limit > recursion_limit_for_pruning:
        print("Hit the recursion limit for pruning!!")
        print("Limit:" + str(recursion_limit_for_pruning))
        print("Low,Sup", low, sup)

    if unknown_counter > 0:
        return ret_box

    if exists_true <= valid_for_exit_pruning and start_recursion_limit <= recursion_limit_for_pruning:
        return clean_co_domain(ret_box,
                               smt_manager,
                               expression_center,
                               divisions_SMT,
                               valid_for_exit_pruning,
                               recursion_limit_for_pruning,
                               start_recursion_limit=start_recursion_limit + 1,
                               dReal=dReal)
    return ret_box
Beispiel #20
0
    def _pbox_dependent_execution(self):
        left_operand_discr_SMT = copy.deepcopy(
            self.leftoperand.get_discretization())
        right_operand_discr_SMT = copy.deepcopy(
            self.rightoperand.get_discretization())

        expression_left = self.smt_triple[0]
        expression_right = self.smt_triple[1]
        smt_manager = self.smt_triple[2]

        expression_center = create_exp_for_BinaryOperation_SMT_LIB(
            expression_left, self.operator, expression_right)

        if self.is_error_computation:
            self.affine_error.update_interval()
            domain_affine_SMT = self.affine_error
            smt_manager.clean_expressions()
            self.symbolic_affine = self.symbolic_error
            constraint_expression = self.rightoperand.name  #symbolic_affine.center
            second_order_lower, second_order_upper = \
                SymbolicToGelpia(self.symbolic_affine.center,self.symbolic_affine.variables).\
                    compute_concrete_bounds(zero_output_epsilon=True)
            center_interval = Interval(second_order_lower, second_order_upper,
                                       True, True, digits_for_range)
            concrete_symbolic_interval = self.symbolic_affine.compute_interval_error(
                center_interval)
            print("Error domain: [" + str(concrete_symbolic_interval.lower) +
                  ", " + str(concrete_symbolic_interval.upper) + "]")

        else:
            domain_affine_SMT = left_operand_discr_SMT.affine.perform_affine_operation(
                self.operator, right_operand_discr_SMT.affine)
            self.symbolic_affine = self.leftoperand.symbolic_affine.perform_affine_operation(
                self.operator, self.rightoperand.symbolic_affine,
                self.real_precision_constraints)
            constraint_expression = None
            center_interval = None
            concrete_symbolic_interval = self.symbolic_affine.compute_interval(
            )
        insides_SMT = []
        tmp_insides_SMT = []

        evaluation_points = set()
        print("Left-Intervals: " + str(len(left_operand_discr_SMT.intervals)))
        print("Right-Intervals: " +
              str(len(right_operand_discr_SMT.intervals)))
        print("Pruning dependent operation...")

        pool = MyPool(processes=num_processes_dependent_operation
                      )  #, maxtasksperchild=3)
        tmp_results = []

        for index_left, left_op_box_SMT in enumerate(
                left_operand_discr_SMT.intervals):
            for index_right, right_op_box_SMT in enumerate(
                    right_operand_discr_SMT.intervals):
                domain_interval = left_op_box_SMT.\
                    interval.perform_interval_operation(self.operator,right_op_box_SMT.interval)
                intersection_interval = domain_interval.intersection(
                    domain_affine_SMT.interval)
                if not intersection_interval == empty_interval:
                    intersection_interval = intersection_interval.intersection(
                        concrete_symbolic_interval)
                    if not intersection_interval == empty_interval:
                        tmp_results.append(
                            pool.apply_async(
                                dependentIteration,
                                args=[
                                    index_left, index_right, smt_manager,
                                    expression_left, expression_center,
                                    expression_right, self.operator,
                                    left_op_box_SMT, right_op_box_SMT,
                                    domain_affine_SMT,
                                    self.is_error_computation,
                                    self.symbolic_affine,
                                    concrete_symbolic_interval,
                                    constraint_expression, center_interval
                                ],
                                callback=tmp_insides_SMT.append))
        print("Number of jobs for dependent operation: " +
              str(len(tmp_results)))
        pool.close()
        pool.join()
        print("\nDone with dependent operation\n")

        for triple in tmp_insides_SMT:
            if not triple[2] == empty_interval:
                inside_box_SMT = PBox(triple[2], "prob", "prob")
                insides_SMT.append(inside_box_SMT)
                left_operand_discr_SMT.intervals[triple[0]].add_kid(
                    inside_box_SMT)
                right_operand_discr_SMT.intervals[triple[1]].add_kid(
                    inside_box_SMT)
                evaluation_points.add(Decimal(inside_box_SMT.interval.lower))
                evaluation_points.add(Decimal(inside_box_SMT.interval.upper))

        evaluation_points = sorted(evaluation_points)

        if len(evaluation_points
               ) > discretization_points and not self.is_error_computation:
            step = round(len(evaluation_points) / discretization_points)
            step = max(1, step)
            evaluation_points = sorted(
                set(evaluation_points[::step] + [evaluation_points[-1]]))

        lp_inst_SMT = LP_with_SMT(self.leftoperand.name,
                                  self.rightoperand.name,
                                  left_operand_discr_SMT.intervals,
                                  right_operand_discr_SMT.intervals,
                                  insides_SMT, evaluation_points)
        upper_bound_cdf_ind_SMT, upper_bound_cdf_val_SMT = lp_inst_SMT.optimize_max(
        )
        lower_bound_cdf_ind_SMT, lower_bound_cdf_val_SMT = lp_inst_SMT.optimize_min(
        )

        print("Done with LP optimization problem")

        if not lower_bound_cdf_ind_SMT == upper_bound_cdf_ind_SMT:
            print("Lists should be identical")
            exit(-1)

        edge_cdf = lower_bound_cdf_ind_SMT
        val_cdf_low = lower_bound_cdf_val_SMT
        val_cdf_up = upper_bound_cdf_val_SMT
        pboxes = from_DSI_to_PBox(edge_cdf, val_cdf_low, edge_cdf, val_cdf_up)
        self.discretization = MixedArithmetic.clone_MixedArith_from_Args(
            domain_affine_SMT, pboxes)
Beispiel #21
0
 def add_constant_string(self, constant):
     constant = Interval(constant, constant, True, True, digits_for_range)
     new_center = self.center.addition(constant)
     return AffineInstance(new_center, copy.deepcopy(self.coefficients))
Beispiel #22
0
    def inverse(self):
        self_interval = self.compute_interval()
        new_coefficients = copy.deepcopy(self.coefficients)

        if Decimal(self_interval.lower) <= Decimal("0.0") <= Decimal(
                self_interval.upper):
            print("Division By Zero")
            exit(-1)

        min_a = find_min_abs_interval(self_interval)
        a = Interval(min_a, min_a, True, True, digits_for_range)
        max_b = find_max_abs_interval(self_interval)
        b = Interval(max_b, max_b, True, True, digits_for_range)
        b_square = b.perform_interval_operation("*", b)
        alpha = Interval("-1.0", "-1.0", True, True,
                         digits_for_range).perform_interval_operation(
                             "/", b_square)
        tmp_a = Interval("1.0", "1.0", True, True,
                         digits_for_range).perform_interval_operation("/", a)
        d_max = tmp_a.perform_interval_operation(
            "-", alpha.perform_interval_operation("*", a))
        tmp_b = Interval("1.0", "1.0", True, True,
                         digits_for_range).perform_interval_operation("/", b)
        d_min = tmp_b.perform_interval_operation(
            "-", alpha.perform_interval_operation("*", b))
        shift = AffineManager.compute_middle_point_given_interval(
            d_min.lower, d_max.upper)
        if Decimal(self_interval.lower) < Decimal("0.0"):
            shift = shift.multiplication(
                Interval("-1.0", "-1.0", True, True, digits_for_range))
        #Error of the approximation with min-range
        #radius=AffineManager.compute_uncertainty_given_interval(d_min, d_max)
        radius = AffineManager.compute_uncertainty_given_interval(
            d_min.lower, d_max.upper)
        #####
        res = AffineInstance(self.center, new_coefficients)
        res = res.mult_interval(alpha)
        res = res.add_constant_interval(shift)
        #The err radius is not shifted or scaled by shift and alpha
        #err_radius=AffineManager.get_new_error_index()
        res.coefficients.update(radius)
        res.update_interval()
        #res.coefficients[err_radius]=radius
        return res
Beispiel #23
0
 def mult_constant_string(self, constant):
     const_interval = Interval(constant, constant, True, True,
                               digits_for_range)
     return self.mult_interval(const_interval)