예제 #1
0
    def _power_a_var(self, first_var: str, second_var: str):

        sign = ""
        if first_var[0] in _SIGN:
            sign = first_var[0]
        first_var_power = str(self._get_power(first_var))

        # Cutting respective power and convert signed numbers
        first_var = convert_signed_number(first_var.split("^")[0], accept_var=True)
        second_var = convert_signed_number(second_var.split("^")[0], accept_var=True)
        second_var = self.solve(convert_to_tokens(second_var), internal=True)
        if is_number(second_var) and float(second_var) != int(float(second_var)):
            raise NotImplementedError("irrational numbers are not accepted as exponent.")
        if is_number(second_var) and float(second_var) < 0:
            raise NotImplementedError(f"Some part of the polynomial var have negative power.")
        if not self._check_have_var(first_var):
            raise NotImplementedError("Cannot power a number by a var for the moment.")
        elif self._check_have_var(second_var):
            raise NotImplementedError("Cannot power a var by a var for the moment.")
        else:
            tokens = []
            tokens = convert_to_tokens(first_var_power + "*" + second_var)
            sum_power = self.solve(tokens, internal=True)
            if float(sum_power) == 0:
                return "1"
            return sign + self._write_power_to_var(var=self.var_name, power=sum_power)
예제 #2
0
def predict(model,
            dataloader,
            example_dict,
            feature_dict,
            prediction_file,
            need_sp_logit_file=False):
    model.eval()
    answer_dict = {}
    sp_dict = {}
    dataloader.refresh()
    total_test_loss = [0] * 5

    for batch in tqdm(dataloader):

        batch['context_mask'] = batch['context_mask'].float()
        start_logits, end_logits, type_logits, sp_logits, start_position, end_position = model(
            batch)

        loss_list = compute_loss(batch, start_logits, end_logits, type_logits,
                                 sp_logits, start_position, end_position)

        for i, l in enumerate(loss_list):
            if not isinstance(l, int):
                total_test_loss[i] += l.item()

        answer_dict_ = convert_to_tokens(
            example_dict, feature_dict, batch['ids'],
            start_position.data.cpu().numpy().tolist(),
            end_position.data.cpu().numpy().tolist(),
            np.argmax(type_logits.data.cpu().numpy(), 1))
        answer_dict.update(answer_dict_)

        predict_support_np = torch.sigmoid(sp_logits).data.cpu().numpy()
        for i in range(predict_support_np.shape[0]):
            cur_sp_pred = []
            cur_id = batch['ids'][i]

            cur_sp_logit_pred = []  # for sp logit output
            for j in range(predict_support_np.shape[1]):
                if j >= len(example_dict[cur_id].sent_names):
                    break
                if need_sp_logit_file:
                    temp_title, temp_id = example_dict[cur_id].sent_names[j]
                    cur_sp_logit_pred.append(
                        (temp_title, temp_id, predict_support_np[i, j]))
                if predict_support_np[i, j] > args.sp_threshold:
                    cur_sp_pred.append(example_dict[cur_id].sent_names[j])
            sp_dict.update({cur_id: cur_sp_pred})

    new_answer_dict = {}
    for key, value in answer_dict.items():
        new_answer_dict[key] = value.replace(" ", "")
    prediction = {'answer': new_answer_dict, 'sp': sp_dict}
    with open(prediction_file, 'w', encoding='utf8') as f:
        json.dump(prediction, f, indent=4, ensure_ascii=False)

    for i, l in enumerate(total_test_loss):
        print("Test Loss{}: {}".format(i, l / len(dataloader)))
    test_loss_record.append(sum(total_test_loss[:3]) / len(dataloader))
예제 #3
0
    def _divide_a_var(self, first_var: str, second_var: str):

        first_var_power = str(self._get_power(first_var))
        second_var_power = str(self._get_power(second_var))

        # Cutting respective power and convert signed numbers
        first_var = convert_signed_number(first_var.split("^")[0], accept_var=True)
        second_var = convert_signed_number(second_var.split("^")[0], accept_var=True)

        if not self._check_have_var(first_var):
            raise NotImplementedError("Cannot divide a number by a var for the moment.")
        elif not self._check_have_var(second_var):
            if second_var == "0.0":
                raise ValueError(
                    "The expression lead to a division by zero : ", first_var, " / ", second_var
                )
            sum_power = first_var_power
            removed_var1_name = first_var.replace(self.var_name, "1")
            tokens = []
            # Signed numbers are already converted.
            tokens = convert_to_tokens(removed_var1_name + "/" + second_var)
            result = self.solve(tokens, internal=True)
            if float(result) != 1 and float(result) != -1:
                if float(sum_power) == 0:
                    return result
                return result + "*" + self._write_power_to_var(var=self.var_name, power=sum_power)
            else:
                if float(sum_power) == 0:
                    return "1"
                elif float(result) == -1:
                    return "-" + self._write_power_to_var(var=self.var_name, power=sum_power)
                else:
                    return self._write_power_to_var(var=self.var_name, power=sum_power)
        else:
            sum_power = str(self.solve([first_var_power, "-", second_var_power], internal=True))

            removed_var1_name = first_var.replace(self.var_name, "1")
            removed_var2_name = second_var.replace(self.var_name, "1")
            tokens = []
            tokens = convert_to_tokens(removed_var1_name + "/" + removed_var2_name)
            result = self.solve(tokens, internal=True)
            if float(sum_power) == 0:
                return result
            return result + "*" + self._write_power_to_var(var=self.var_name, power=sum_power)
예제 #4
0
    def _parse_expression(self):
        print("Expression before parsing : ",
              self.expression) if self._verbose is True else None

        # Removing all spaces
        self.expression = self.expression.replace(" ", "")

        print("Removing all space from the expression : ",
              self.expression) if self._verbose is True else None

        # Checking if there is any sign or operator in the expression
        ok = False
        for operator in _OPERATORS + _SIGN + "=":
            if operator in self.expression:
                ok = True
        if ok is False:
            raise NothingToDoError(
                "There is no operators or sign in the expression. Nothing to do here."
            )

        # To put before convert_signed_number because it is creating parenthesis
        self.expression = parse_sign(self.expression)
        print("Parsing signs : ",
              self.expression) if self._verbose is True else None

        self._get_vars()
        print("vars = ", self._vars_set) if self._verbose is True else None

        self.expression = convert_signed_number(expression=self.expression,
                                                accept_var=True)

        print("Convert signed numbers : ",
              self.expression) if self._verbose is True else None

        self._add_implicit_cross_operator_when_parenthesis()
        self.expression = add_implicit_cross_operator_for_vars(
            self._vars_set, self.expression)

        print("Convert implicit multiplication : ",
              self.expression) if self._verbose is True else None

        # Checking args here before converting to token
        self._check_args()

        # Transforming expression to tokens
        self.expression = convert_to_tokens(self.expression)

        print("Convert to token : ",
              self.expression) if self._verbose is True else None
        self._removing_trailing_zero_and_converting_numbers_to_float()
        print("Removing extra zero and converting numbers to float: ",
              self.expression) if self._verbose is True else None
예제 #5
0
 def _push_right_to_left(self):
     for key, right_value in self._polynom_dict_right.items():
         try:
             left_value = self._polynom_dict_left[key]
         except:
             left_value = 0.0
         tokens = convert_to_tokens(
             convert_signed_number(
                 parse_sign(
                     add_implicit_cross_operator_for_vars(list(self.var_name), str(left_value))
                     + "-"
                     + add_implicit_cross_operator_for_vars(
                         list(self.var_name), str(right_value)
                     )
                 ),
                 accept_var=True,
             )
         )
         self._polynom_dict_left[key] = self._calculator.solve(
             tokens=tokens, verbose=self._force_calculator_verbose
         )
예제 #6
0
    def _solve_polynom_degree_two(self):
        try:
            a = get_var_multiplier(self._polynom_dict_left["a"], var_name=self.var_name)
        except:
            a = 0.0
        try:
            b = get_var_multiplier(self._polynom_dict_left["b"], var_name=self.var_name)
        except:
            b = 0.0
        try:
            c = float(self._polynom_dict_left["c"])
        except:
            c = 0.0

        print("a = ", a, " b = ", b, " c = ", c) if self._verbose is True else None

        discriminant = self._get_discriminant(a, b, c)
        if discriminant > 0:
            print("The discriminant is strictly positive.")
        elif discriminant == 0:
            print("The discriminant is exactly zero.")
        else:
            print("The discriminant is strictly negative.")
        print("discriminant = ", discriminant)
        if discriminant > 0:
            self.solution = []
            if a == 0:
                raise ValueError(
                    "The expression lead to a division by zero : ",
                    float(str((-b + my_sqrt(discriminant)))),
                    " / ",
                    a,
                )
            solution_one = str((-b + my_sqrt(discriminant)) / (2 * a))
            solution_two = str((-b - my_sqrt(discriminant)) / (2 * a))
            if solution_one == "-0.0":
                solution_one = "0.0"
            if solution_two == "-0.0":
                solution_two = "0.0"
            self.solution.append(str(my_round(float(solution_one), 6)))
            self.solution.append(str(my_round(float(solution_two), 6)))
        elif discriminant == 0:
            if a == 0:
                raise ValueError(
                    "The expression lead to a division by zero : ",
                    float(str((-b + my_sqrt(discriminant)))),
                    " / ",
                    a,
                )
            self.solution = str((-b) / (2 * a))
            if self.solution == "-0.0":
                self.solution = "0.0"
        else:
            print("There is two solutions in complex number.")
            self.solution = []
            discriminant = -discriminant
            solution_one = convert_signed_number(
                f"{-b} / (2 * {a}) + i * {my_sqrt(discriminant)} / (2 * {a})".replace(" ", "")
            )
            tokens = convert_to_tokens(
                convert_signed_number(parse_sign(solution_one), accept_var=True)
            )
            self.solution.append(
                self._calculator.solve(tokens=tokens, verbose=self._force_calculator_verbose)
            )

            solution_two = f"{-b} / (2 * {a}) - i * {my_sqrt(discriminant)} / (2 * {a})".replace(
                " ", ""
            )
            tokens = convert_to_tokens(
                convert_signed_number(parse_sign(solution_two), accept_var=True)
            )
            self.solution.append(
                self._calculator.solve(tokens=tokens, verbose=self._force_calculator_verbose)
            )
예제 #7
0
    def _multiply_a_var(self, first_var: str, second_var: str):

        first_var_power = str(self._get_power(first_var))
        second_var_power = str(self._get_power(second_var))

        # Cutting respective power and convert signed numbers
        first_var = convert_signed_number(first_var.split("^")[0], accept_var=True)
        second_var = convert_signed_number(second_var.split("^")[0], accept_var=True)

        if not self._check_have_var(first_var):
            if first_var == "0.0":
                return "0.0"
            else:
                sum_power = second_var_power
                remove_var_name = second_var.replace(self.var_name, "1")
                tokens = []
                tokens = convert_to_tokens(first_var + "*" + remove_var_name)
                result = self.solve(tokens, internal=True)
                if float(result) != 1 and float(result) != -1:
                    if float(sum_power) == 0:
                        return result
                    return (
                        result + "*" + self._write_power_to_var(var=self.var_name, power=sum_power)
                    )
                else:
                    if float(sum_power) == 0:
                        return "1"
                    elif float(result) == -1:
                        return "-" + self._write_power_to_var(var=self.var_name, power=sum_power)
                    else:
                        return self._write_power_to_var(var=self.var_name, power=sum_power)

        elif not self._check_have_var(second_var):
            sum_power = first_var_power

            remove_var_name = first_var.replace(self.var_name, "1")
            tokens = []
            tokens = convert_to_tokens(remove_var_name + "*" + second_var)
            result = self.solve(tokens, internal=True)
            if float(result) != 1 and float(result) != -1:
                if float(sum_power) == 0:
                    return result
                return result + "*" + self._write_power_to_var(var=self.var_name, power=sum_power)
            else:
                if float(sum_power) == 0:
                    return "1"
                elif float(result) == -1:
                    return "-" + self._write_power_to_var(var=self.var_name, power=sum_power)
                else:
                    return self._write_power_to_var(var=self.var_name, power=sum_power)
        # Both have var.
        else:
            sum_power = str(self.solve([first_var_power, "+", second_var_power], internal=True))

            removed_var1_name = first_var.replace(self.var_name, "1")
            removed_var2_name = second_var.replace(self.var_name, "1")
            tokens = []
            tokens = convert_to_tokens(removed_var1_name + "*" + removed_var2_name)

            result = self.solve(tokens, internal=True)
            if float(result) != 1 and float(result) != -1:
                if float(sum_power) == 0:
                    return result
                return result + "*" + self._write_power_to_var(var=self.var_name, power=sum_power)
            else:
                if float(sum_power) == 0:
                    return "1"
                elif float(result) == -1:
                    return "-" + self._write_power_to_var(var=self.var_name, power=sum_power)
                else:
                    return self._write_power_to_var(var=self.var_name, power=sum_power)
예제 #8
0
    def _add_or_substract_var_to_var(self, operator: str, first_var: str, second_var: str):
        pattern = self.var_name
        # Checking if multiple var in first_var (ex : x + X ^ 2)
        if len(re.findall(pattern=pattern, string=first_var)) > 1:
            second_var_power = str(float(self._get_power(second_var)))
            if second_var_power != "1.0":
                # regex that match any sign or none, followed by any number or none
                # followed by the var name followed by the power of the var
                pattern = "[{sign}]*[.\d]*[\*]*{var_name}\^{second_var_power}".format(
                    var_name=self.var_name, second_var_power=second_var_power, sign=_SIGN
                )
            else:
                # Same for simple X, the var name shouln't be followed by a power operator
                pattern = "[{sign}]*[.\d]*[\*]*{var_name}(?!\^)".format(
                    var_name=self.var_name, second_var_power=second_var_power, sign=_SIGN
                )
            split = re.split(pattern=pattern, string=first_var)
            if len(split) > 1:
                search = re.search(pattern=pattern, string=first_var)
                if search is not None:
                    # Cutting respective power and convert signed numbers
                    first_var = add_implicit_cross_operator_for_vars(
                        vars_list=list(self.var_name),
                        expression=convert_signed_number(search.group(0), accept_var=True),
                    )
                    second_var = add_implicit_cross_operator_for_vars(
                        vars_list=list(self.var_name),
                        expression=convert_signed_number(second_var, accept_var=True),
                    )
                    tokens = convert_to_tokens(first_var + operator + second_var)
                    result = self.solve(tokens=tokens, internal=True)
                    if result == "0.0":
                        return parse_sign("".join(split))
                    else:
                        return parse_sign(result + "+" + "".join(split))

        first_var_power = str(self._get_power(first_var))
        second_var_power = str(self._get_power(second_var))

        # Different power
        if first_var_power != second_var_power:
            return first_var + operator + second_var

        # Cutting respective power and convert signed numbers
        first_var = add_implicit_cross_operator_for_vars(
            vars_list=list(self.var_name),
            expression=convert_signed_number(first_var.split("^")[0], accept_var=True),
        )
        second_var = add_implicit_cross_operator_for_vars(
            vars_list=list(self.var_name),
            expression=convert_signed_number(second_var.split("^")[0], accept_var=True),
        )

        removed_var1_name = first_var.replace(self.var_name, "1")
        removed_var2_name = second_var.replace(self.var_name, "1")

        tokens = convert_to_tokens(removed_var1_name + operator + removed_var2_name)
        result = self.solve(tokens, internal=True)
        if float(result) == 0:
            return "0.0"
        elif float(result) == 1:
            return self._write_power_to_var(var=self.var_name, power=first_var_power)
        else:
            return str(result) + self._write_power_to_var(var=self.var_name, power=first_var_power)