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)
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))
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)
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
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 )
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) )
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)
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)