def apply(self, eqs, vars, evaluation): 'Solve[eqs_, vars_]' vars_original = vars head_name = vars.get_head_name() if head_name == 'System`List': vars = vars.leaves else: vars = [vars] for var in vars: if ((var.is_atom() and not var.is_symbol()) or # noqa head_name in ('System`Plus', 'System`Times', 'System`Power') or 'System`Constant' in var.get_attributes(evaluation.definitions)): evaluation.message('Solve', 'ivar', vars_original) return eqs_original = eqs if eqs.get_head_name() in ('System`List', 'System`And'): eqs = eqs.leaves else: eqs = [eqs] sympy_eqs = [] sympy_denoms = [] for eq in eqs: if eq == SymbolTrue: pass elif eq == SymbolFalse: return Expression('List') elif not eq.has_form('Equal', 2): return evaluation.message('Solve', 'eqf', eqs_original) else: left, right = eq.leaves left = left.to_sympy() right = right.to_sympy() if left is None or right is None: return eq = left - right eq = sympy.together(eq) eq = sympy.cancel(eq) sympy_eqs.append(eq) numer, denom = eq.as_numer_denom() sympy_denoms.append(denom) vars_sympy = [var.to_sympy() for var in vars] if None in vars_sympy: return # delete unused variables to avoid SymPy's # PolynomialError: Not a zero-dimensional system # in e.g. Solve[x^2==1&&z^2==-1,{x,y,z}] all_vars = vars[:] all_vars_sympy = vars_sympy[:] vars = [] vars_sympy = [] for var, var_sympy in zip(all_vars, all_vars_sympy): pattern = Pattern.create(var) if not eqs_original.is_free(pattern, evaluation): vars.append(var) vars_sympy.append(var_sympy) def transform_dict(sols): if not sols: yield sols for var, sol in sols.items(): rest = sols.copy() del rest[var] rest = transform_dict(rest) if not isinstance(sol, (tuple, list)): sol = [sol] if not sol: for r in rest: yield r else: for r in rest: for item in sol: new_sols = r.copy() new_sols[var] = item yield new_sols break def transform_solution(sol): if not isinstance(sol, dict): if not isinstance(sol, (list, tuple)): sol = [sol] sol = dict(list(zip(vars_sympy, sol))) return transform_dict(sol) if not sympy_eqs: sympy_eqs = True elif len(sympy_eqs) == 1: sympy_eqs = sympy_eqs[0] try: if isinstance(sympy_eqs, bool): result = sympy_eqs else: result = sympy.solve(sympy_eqs, vars_sympy) if not isinstance(result, list): result = [result] if (isinstance(result, list) and len(result) == 1 and result[0] is True): return Expression('List', Expression('List')) if result == [None]: return Expression('List') results = [] for sol in result: results.extend(transform_solution(sol)) result = results if any(sol and any(var not in sol for var in all_vars_sympy) for sol in result): evaluation.message('Solve', 'svars') # Filter out results for which denominator is 0 # (SymPy should actually do that itself, but it doesn't!) result = [ sol for sol in result if all( sympy.simplify(denom.subs(sol)) != 0 for denom in sympy_denoms) ] return Expression( 'List', *(Expression( 'List', *(Expression('Rule', var, from_sympy(sol[var_sympy])) for var, var_sympy in zip(vars, vars_sympy) if var_sympy in sol)) for sol in result)) except sympy.PolynomialError: # raised for e.g. Solve[x^2==1&&z^2==-1,{x,y,z}] when not deleting # unused variables beforehand pass except NotImplementedError: pass except TypeError as exc: if str(exc).startswith("expected Symbol, Function or Derivative"): evaluation.message('Solve', 'ivar', vars_original)
def apply(self, expr, moff, mon, evaluation): 'Quiet[expr_, moff_, mon_]' def get_msg_list(expr): if expr.has_form('MessageName', 2): expr = Expression('List', expr) if expr.get_name() == 'System`All': all = True messages = [] elif expr.get_name() == 'System`None': all = False messages = [] elif expr.has_form('List', None): all = False messages = [] for item in expr.leaves: if item.has_form('MessageName', 2): symbol = item.leaves[0].get_name() tag = item.leaves[1].get_string_value() if symbol and tag: messages.append((symbol, tag)) else: raise ValueError else: raise ValueError else: raise ValueError return all, messages old_quiet_all, old_quiet_messages = \ evaluation.quiet_all, evaluation.quiet_messages.copy() try: quiet_expr = Expression('Quiet', expr, moff, mon) try: off_all, off_messages = get_msg_list(moff) except ValueError: evaluation.message('Quiet', 'anmlist', 2, quiet_expr) return try: on_all, on_messages = get_msg_list(mon) except ValueError: evaluation.message('Quiet', 'anmlist', 2, quiet_expr) return if off_all and on_all: evaluation.message('Quiet', 'allall', quiet_expr) return evaluation.quiet_all = off_all conflict = [] for off in off_messages: if off in on_messages: conflict.append(off) break if conflict: evaluation.message( 'Quiet', 'conflict', quiet_expr, Expression( 'List', *(Expression('MessageName', Symbol(symbol), String(tag)) for symbol, tag in conflict))) return for off in off_messages: evaluation.quiet_messages.add(off) for on in on_messages: evaluation.quiet_messages.discard(on) if on_all: evaluation.quiet_messages = set() return expr.evaluate(evaluation) finally: evaluation.quiet_all, evaluation.quiet_messages =\ old_quiet_all, old_quiet_messages
def apply_wrong(self, expr, x, other, evaluation): 'D[expr_, {x_, other___}]' arg = Expression('List', x, *other.get_sequence()) evaluation.message('D', 'dvar', arg) return Expression('D', expr, arg)
def callback(level): return Expression(f, level)
def apply(self, expr, evaluation): 'Dimensions[expr_]' return Expression('List', *[ Integer(dim) for dim in get_dimensions(expr)])
exc_result = Symbol('$Aborted') if exc_result is not None: self.recursion_depth = 0 result = self.format_output(exc_result) self.results.append(Result(self.out, result, line_no)) self.out = [] finally: self.stop() history_length = self.get_config_value('$HistoryLength', 100) if history_length is None or history_length > 100: history_length = 100 line = line_no - history_length while line > 0: unset_in = self.definitions.unset('In', Expression('In', line)) unset_out = self.definitions.unset('Out', Expression('Out', line)) if not (unset_in or unset_out): break line -= 1 if last_parse_error is not None: self.recursion_depth = 0 self.stopped = False self.message('General', 'syntax', unicode(last_parse_error)) self.results.append(Result(self.out, None, None)) def get_stored_result(self, result): from mathics.core.expression import Symbol
def evaluate(self, evaluation): return Expression('List', String(self.value))
def lhs(expr): return Expression('Format', expr, Symbol(format))
def rhs(expr): if expr.has_form('Infix', None): expr = Expression( Expression('HoldForm', expr.head), *expr.leaves) return Expression('InputForm', expr)
def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False): name = lhs.get_head_name() if name in system_symbols('OwnValues', 'DownValues', 'SubValues', 'UpValues', 'NValues', 'Options', 'DefaultValues', 'Attributes', 'Messages'): if len(lhs.leaves) != 1: evaluation.message_args(name, len(lhs.leaves), 1) return False tag = lhs.leaves[0].get_name() if not tag: evaluation.message(name, 'sym', lhs.leaves[0], 1) return False if tags is not None and tags != [tag]: evaluation.message(name, 'tag', Symbol(name), Symbol(tag)) return False if (name != 'System`Attributes' and 'System`Protected' # noqa in evaluation.definitions.get_attributes(tag)): evaluation.message(name, 'wrsym', Symbol(tag)) return False if name == 'System`Options': option_values = rhs.get_option_values(evaluation) if option_values is None: evaluation.message(name, 'options', rhs) return False evaluation.definitions.set_options(tag, option_values) elif name == 'System`Attributes': attributes = get_symbol_list( rhs, lambda item: evaluation.message(name, 'sym', item, 1)) if attributes is None: return False if 'System`Locked' in evaluation.definitions.get_attributes( tag): evaluation.message(name, 'locked', Symbol(tag)) return False evaluation.definitions.set_attributes(tag, attributes) else: rules = rhs.get_rules_list() if rules is None: evaluation.message(name, 'vrule', lhs, rhs) return False evaluation.definitions.set_values(tag, name, rules) return True form = '' nprec = None default = False message = False allow_custom_tag = False focus = lhs if name == 'System`N': if len(lhs.leaves) not in (1, 2): evaluation.message_args('N', len(lhs.leaves), 1, 2) return False if len(lhs.leaves) == 1: nprec = Symbol('MachinePrecision') else: nprec = lhs.leaves[1] focus = lhs.leaves[0] lhs = Expression('N', focus, nprec) elif name == 'System`MessageName': if len(lhs.leaves) != 2: evaluation.message_args('MessageName', len(lhs.leaves), 2) return False focus = lhs.leaves[0] message = True elif name == 'System`Default': if len(lhs.leaves) not in (1, 2, 3): evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3) return False focus = lhs.leaves[0] default = True elif name == 'System`Format': if len(lhs.leaves) not in (1, 2): evaluation.message_args('Format', len(lhs.leaves), 1, 2) return False if len(lhs.leaves) == 2: form = lhs.leaves[1].get_name() if not form: evaluation.message('Format', 'fttp', lhs.leaves[1]) return False else: form = system_symbols('StandardForm', 'TraditionalForm', 'OutputForm', 'TeXForm', 'MathMLForm') lhs = focus = lhs.leaves[0] else: allow_custom_tag = True focus = focus.evaluate_leaves(evaluation) if tags is None and not upset: name = focus.get_lookup_name() if not name: evaluation.message(self.get_name(), 'setraw', focus) return False tags = [name] elif upset: if allow_custom_tag: tags = [] if focus.is_atom(): evaluation.message(self.get_name(), 'normal') return False for leaf in focus.leaves: name = leaf.get_lookup_name() tags.append(name) else: tags = [focus.get_lookup_name()] else: allowed_names = [focus.get_lookup_name()] if allow_custom_tag: for leaf in focus.get_leaves(): allowed_names.append(leaf.get_lookup_name()) for name in tags: if name not in allowed_names: evaluation.message(self.get_name(), 'tagnfd', Symbol(name)) return False ignore_protection = False rhs_int_value = rhs.get_int_value() lhs_name = lhs.get_name() if lhs_name == 'System`$RecursionLimit': # if (not rhs_int_value or rhs_int_value < 20) and not # rhs.get_name() == 'System`Infinity': if (not rhs_int_value or rhs_int_value < 20 or rhs_int_value > settings.MAX_RECURSION_DEPTH): # nopep8 evaluation.message('$RecursionLimit', 'limset', rhs) return False try: set_recursionlimit(rhs_int_value) except OverflowError: # TODO: Message return False ignore_protection = True elif lhs_name == 'System`$ModuleNumber': if not rhs_int_value or rhs_int_value <= 0: evaluation.message('$ModuleNumber', 'set', rhs) return False ignore_protection = True elif lhs_name in ('System`$Line', 'System`$HistoryLength'): if rhs_int_value is None or rhs_int_value < 0: evaluation.message(lhs_name, 'intnn', rhs) return False ignore_protection = True elif lhs_name == 'System`$RandomState': # TODO: allow setting of legal random states! # (but consider pickle's insecurity!) evaluation.message('$RandomState', 'rndst', rhs) return False elif lhs_name == 'System`$Context': new_context = rhs.get_string_value() if new_context is None or not valid_context_name( new_context, allow_initial_backquote=True): evaluation.message(lhs_name, 'cxset', rhs) return False # With $Context in Mathematica you can do some strange # things: e.g. with $Context set to Global`, something # like: # $Context = "`test`"; newsym # is accepted and creates Global`test`newsym. # Implement this behaviour by interpreting # $Context = "`test`" # as # $Context = $Context <> "test`" # if new_context.startswith('`'): new_context = (evaluation.definitions.get_current_context() + new_context.lstrip('`')) evaluation.definitions.set_current_context(new_context) ignore_protection = True return True elif lhs_name == 'System`$ContextPath': context_path = [s.get_string_value() for s in rhs.get_leaves()] if rhs.has_form('List', None) and all( valid_context_name(s) for s in context_path): evaluation.definitions.set_context_path(context_path) ignore_protection = True return True else: evaluation.message(lhs_name, 'cxlist', rhs) return False elif lhs_name == 'System`$MinPrecision': # $MinPrecision = Infinity is not allowed if rhs_int_value is not None and rhs_int_value >= 0: ignore_protection = True max_prec = evaluation.definitions.get_config_value( '$MaxPrecision') if max_prec is not None and max_prec < rhs_int_value: evaluation.message('$MinPrecision', 'preccon', Symbol('$MinPrecision')) return True else: evaluation.message(lhs_name, 'precset', lhs, rhs) return False elif lhs_name == 'System`$MaxPrecision': if rhs.has_form('DirectedInfinity', 1) and rhs.leaves[0].get_int_value() == 1: ignore_protection = True elif rhs_int_value is not None and rhs_int_value > 0: ignore_protection = True min_prec = evaluation.definitions.get_config_value( '$MinPrecision') if min_prec is not None and rhs_int_value < min_prec: evaluation.message('$MaxPrecision', 'preccon', Symbol('$MaxPrecision')) ignore_protection = True return True else: evaluation.message(lhs_name, 'precset', lhs, rhs) return False rhs_name = rhs.get_head_name() if rhs_name == 'System`Condition': if len(rhs.leaves) != 2: evaluation.message_args('Condition', len(rhs.leaves), 2) return False else: lhs = Expression('Condition', lhs, rhs.leaves[1]) rhs = rhs.leaves[0] rule = Rule(lhs, rhs) count = 0 defs = evaluation.definitions for tag in tags: if (not ignore_protection and 'System`Protected' # noqa in evaluation.definitions.get_attributes(tag)): if lhs.get_name() == tag: evaluation.message(self.get_name(), 'wrsym', Symbol(tag)) else: evaluation.message(self.get_name(), 'write', Symbol(tag), lhs) continue count += 1 if form: defs.add_format(tag, rule, form) elif nprec: defs.add_nvalue(tag, rule) elif default: defs.add_default(tag, rule) elif message: defs.add_message(tag, rule) else: if upset: defs.add_rule(tag, rule, position='up') else: defs.add_rule(tag, rule) if count == 0: return False return True
def format_definition(self, symbol, evaluation, grid=True): 'StandardForm,TraditionalForm,OutputForm: Definition[symbol_]' lines = [] def print_rule(rule, up=False, lhs=lambda l: l, rhs=lambda r: r): evaluation.check_stopped() if isinstance(rule, Rule): r = rhs( rule.replace.replace_vars({ 'System`Definition': Expression('HoldForm', Symbol('Definition')) })) lines.append( Expression( 'HoldForm', Expression(up and 'UpSet' or 'Set', lhs(rule.pattern.expr), r))) name = symbol.get_name() if not name: evaluation.message('Definition', 'sym', symbol, 1) return attributes = evaluation.definitions.get_attributes(name) definition = evaluation.definitions.get_user_definition(name, create=False) all = evaluation.definitions.get_definition(name) if attributes: attributes = list(attributes) attributes.sort() lines.append( Expression( 'HoldForm', Expression( 'Set', Expression('Attributes', symbol), Expression( 'List', *(Symbol(attribute) for attribute in attributes))))) if definition is not None and 'System`ReadProtected' not in attributes: for rule in definition.ownvalues: print_rule(rule) for rule in definition.downvalues: print_rule(rule) for rule in definition.subvalues: print_rule(rule) for rule in definition.upvalues: print_rule(rule, up=True) for rule in definition.nvalues: print_rule(rule) formats = sorted(definition.formatvalues.items()) for format, rules in formats: for rule in rules: def lhs(expr): return Expression('Format', expr, Symbol(format)) def rhs(expr): if expr.has_form('Infix', None): expr = Expression( Expression('HoldForm', expr.head), *expr.leaves) return Expression('InputForm', expr) print_rule(rule, lhs=lhs, rhs=rhs) for rule in all.defaultvalues: print_rule(rule) if all.options: options = sorted(all.options.items()) lines.append( Expression( 'HoldForm', Expression( 'Set', Expression('Options', symbol), Expression( 'List', *(Expression('Rule', Symbol(name), value) for name, value in options))))) if grid: if lines: return Expression( 'Grid', Expression('List', *(Expression('List', line) for line in lines)), Expression('Rule', Symbol('ColumnAlignments'), Symbol('Left'))) else: return Symbol('Null') else: for line in lines: evaluation.print_out(Expression('InputForm', line)) return Symbol('Null')
def match( self, yield_func, expression, vars, evaluation, head=None, leaf_index=None, leaf_count=None, fully=True, wrap_oneid=True, ): evaluation.check_stopped() attributes = self.head.get_attributes(evaluation.definitions) if "System`Flat" not in attributes: fully = True if not expression.is_atom(): # don't do this here, as self.get_pre_choices changes the # ordering of the leaves! # if self.leaves: # next_leaf = self.leaves[0] # next_leaves = self.leaves[1:] def yield_choice(pre_vars): next_leaf = self.leaves[0] next_leaves = self.leaves[1:] # "leading_blanks" below handles expressions with leading Blanks H[x_, y_, ...] # much more efficiently by not calling get_match_candidates_count() on leaves # that have already been matched with one of the leading Blanks. this approach # is only valid for Expressions that are not Orderless (as with Orderless, the # concept of leading items does not exist). # # simple performance test case: # # f[x_, {a__, b_}] = 0; # f[x_, y_] := y + Total[x]; # First[Timing[f[Range[5000], 1]]]" # # without "leading_blanks", Range[5000] will be tested against {a__, b_} in a # call to get_match_candidates_count(), which is slow. unmatched_leaves = expression.leaves leading_blanks = "System`Orderless" not in attributes for leaf in self.leaves: match_count = leaf.get_match_count() if leading_blanks: if tuple(match_count) == ( 1, 1, ): # Blank? (i.e. length exactly 1?) if not unmatched_leaves: raise StopGenerator_ExpressionPattern_match() if not leaf.does_match(unmatched_leaves[0], evaluation, pre_vars): raise StopGenerator_ExpressionPattern_match() unmatched_leaves = unmatched_leaves[1:] else: leading_blanks = False if not leading_blanks: candidates = leaf.get_match_candidates_count( unmatched_leaves, expression, attributes, evaluation, pre_vars, ) if candidates < match_count[0]: raise StopGenerator_ExpressionPattern_match() # for new_vars, rest in self.match_leaf( # nopep8 # self.leaves[0], self.leaves[1:], ([], expression.leaves), # pre_vars, expression, attributes, evaluation, first=True, # fully=fully, leaf_count=len(self.leaves), # wrap_oneid=expression.get_head_name() != 'System`MakeBoxes'): # def yield_leaf(new_vars, rest): # yield_func(new_vars, rest) self.match_leaf( yield_func, next_leaf, next_leaves, ([], expression.leaves), pre_vars, expression, attributes, evaluation, first=True, fully=fully, leaf_count=len(self.leaves), wrap_oneid=expression.get_head_name() != "System`MakeBoxes", ) # for head_vars, _ in self.head.match(expression.get_head(), vars, # evaluation): def yield_head(head_vars, _): if self.leaves: # pre_choices = self.get_pre_choices( # expression, attributes, head_vars) # for pre_vars in pre_choices: self.get_pre_choices(yield_choice, expression, attributes, head_vars) else: if not expression.leaves: yield_func(head_vars, None) else: return try: self.head.match(yield_head, expression.get_head(), vars, evaluation) except StopGenerator_ExpressionPattern_match: return if (wrap_oneid and "System`OneIdentity" in attributes and expression.get_head() != self.head # nopep8 and expression != self.head): # and 'OneIdentity' not in # (expression.get_attributes(evaluation.definitions) | # expression.get_head().get_attributes(evaluation.definitions)): new_expression = Expression(self.head, expression) for leaf in self.leaves: leaf.match_count = leaf.get_match_count() leaf.candidates = [expression] # leaf.get_match_candidates( # new_expression.leaves, new_expression, attributes, # evaluation, vars) if len(leaf.candidates) < leaf.match_count[0]: return # for new_vars, rest in self.match_leaf( # self.leaves[0], self.leaves[1:], # ([], [expression]), vars, new_expression, attributes, # evaluation, first=True, fully=fully, # leaf_count=len(self.leaves), wrap_oneid=True): # def yield_leaf(new_vars, rest): # yield_func(new_vars, rest) self.match_leaf( yield_func, self.leaves[0], self.leaves[1:], ([], [expression]), vars, new_expression, attributes, evaluation, first=True, fully=fully, leaf_count=len(self.leaves), wrap_oneid=True, )
def apply_makeboxes(self, x, y, f, evaluation): 'MakeBoxes[Subscript[x_, y__], f:StandardForm|TraditionalForm]' y = y.get_sequence() return Expression('SubscriptBox', Expression('MakeBoxes', x, f), *list_boxes(y, f))
def transform_item(item): if depth > 2: return Expression(self.get_name(), item, new_depth) else: return item
def evaluate(self, evaluation) -> Expression: return Expression("List", *(String(arg) for arg in sys.argv))
def apply_constraints(self, f, vars, evaluation): 'Minimize[f_?ListQ, vars_?ListQ]' head_name = vars.get_head_name() vars_or = vars vars = vars.leaves for var in vars: if ((var.is_atom() and not var.is_symbol()) or # noqa head_name in ('System`Plus', 'System`Times', 'System`Power') or 'System`Constant' in var.get_attributes(evaluation.definitions)): evaluation.message('Minimize', 'ivar', vars_or) return vars_sympy = [var.to_sympy() for var in vars] constraints = [function for function in f.leaves] objective_function = constraints[0].to_sympy() constraints = constraints[1:] g_functions = [] h_functions = [] g_variables = [] h_variables = [] for constraint in constraints: left, right = constraint.leaves head_name = constraint.get_head_name() left = left.to_sympy() right = right.to_sympy() if head_name == 'System`LessEqual' or head_name == 'System`Less': eq = left - right eq = sympy.together(eq) eq = sympy.cancel(eq) g_functions.append(eq) g_variables.append( sympy.Symbol('kkt_g' + str(len(g_variables)))) elif head_name == 'System`GreaterEqual' or head_name == 'System`Greater': eq = -1 * (left - right) eq = sympy.together(eq) eq = sympy.cancel(eq) g_functions.append(eq) g_variables.append( sympy.Symbol('kkt_g' + str(len(g_variables)))) elif head_name == 'System`Equal': eq = left - right eq = sympy.together(eq) eq = sympy.cancel(eq) h_functions.append(eq) h_variables.append( sympy.Symbol('kkt_h' + str(len(h_variables)))) equations = [] for variable in vars_sympy: equation = sympy.diff(objective_function, variable) for i in range(len(g_variables)): g_variable = g_variables[i] g_function = g_functions[i] equation = equation + g_variable * sympy.diff( g_function, variable) for i in range(len(h_variables)): h_variable = h_variables[i] h_function = h_functions[i] equation = equation + h_variable * sympy.diff( h_function, variable) equations.append(equation) for i in range(len(g_variables)): g_variable = g_variables[i] g_function = g_functions[i] equations.append(g_variable * g_function) for i in range(len(h_variables)): h_variable = h_variables[i] h_function = h_functions[i] equations.append(h_variable * h_function) all_variables = vars_sympy + g_variables + h_variables candidates_tmp = sympy.solve(equations, all_variables, dict=True) candidates = [] for candidate in candidates_tmp: if len(candidate) != len(vars_sympy): for variable in candidate: for i in range(len(candidate), len(vars_sympy)): candidate[variable] = candidate[variable].subs( {vars_sympy[i]: 1}) for i in range(len(candidate), len(vars_sympy)): candidate[vars_sympy[i]] = 1 candidates.append(candidate) kkt_candidates = [] for candidate in candidates: kkt_ok = True sum_constraints = 0 for i in range(len(g_variables)): g_variable = g_variables[i] g_function = g_functions[i] if candidate[g_variable] < 0: kkt_ok = False if candidate[g_variable] * g_function.subs(candidate) != 0: kkt_ok = False sum_constraints = sum_constraints + candidate[g_variable] for i in range(len(h_variables)): h_variable = h_variables[i] h_function = h_functions[i] sum_constraints = sum_constraints + abs(candidate[h_variable]) if sum_constraints <= 0: kkt_ok = False if not kkt_ok: continue kkt_candidates.append(candidate) hessian = sympy.Matrix([[sympy.diff(deriv, x) for x in all_variables] for deriv in equations]) for i in range(0, len(all_variables) - len(vars_sympy)): hessian.col_del(len(all_variables) - i - 1) hessian.row_del(len(all_variables) - i - 1) minimum_list = [] for candidate in kkt_candidates: eigenvals = hessian.subs(candidate).eigenvals() positives_eigenvalues = 0 negatives_eigenvalues = 0 for val in eigenvals: val = complex(sympy.N(val, chop=True)) if val.imag == 0: val = val.real if val < 0: negatives_eigenvalues += 1 elif val > 0: positives_eigenvalues += 1 if positives_eigenvalues + negatives_eigenvalues != len(eigenvals): continue if positives_eigenvalues == len(eigenvals): for g_variable in g_variables: del candidate[g_variable] for h_variable in h_variables: del candidate[h_variable] minimum_list.append(candidate) return Expression( 'List', *(Expression( 'List', from_sympy(objective_function.subs(minimum).simplify()), [ Expression('Rule', from_sympy(list(minimum.keys())[i]), from_sympy(list(minimum.values())[i])) for i in range(len(vars_sympy)) ]) for minimum in minimum_list))
def apply_full(self, xmin, ymin, zmin, xmax, ymax, zmax, evaluation): 'Cuboid[{xmin_, ymin_, zmin_}, {xmax_, ymax_, zmax_}]' try: xmin, ymin, zmin = [ value.to_number(n_evaluation=evaluation) for value in (xmin, ymin, zmin) ] xmax, ymax, zmax = [ value.to_number(n_evaluation=evaluation) for value in (xmax, ymax, zmax) ] except NumberError: # TODO return if (xmax <= xmin) or (ymax <= ymin) or (zmax <= zmin): # TODO return polygons = [ # X Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmin, ymax, zmin), Expression('List', xmin, ymax, zmax)), Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmin, ymin, zmax), Expression('List', xmin, ymax, zmax)), Expression('List', Expression('List', xmax, ymin, zmin), Expression('List', xmax, ymax, zmin), Expression('List', xmax, ymax, zmax)), Expression('List', Expression('List', xmax, ymin, zmin), Expression('List', xmax, ymin, zmax), Expression('List', xmax, ymax, zmax)), # Y Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmax, ymin, zmin), Expression('List', xmax, ymin, zmax)), Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmin, ymin, zmax), Expression('List', xmax, ymin, zmax)), Expression('List', Expression('List', xmin, ymax, zmin), Expression('List', xmax, ymax, zmin), Expression('List', xmax, ymax, zmax)), Expression('List', Expression('List', xmin, ymax, zmin), Expression('List', xmin, ymax, zmax), Expression('List', xmax, ymax, zmax)), # Z Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmin, ymax, zmin), Expression('List', xmax, ymax, zmin)), Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmax, ymin, zmin), Expression('List', xmax, ymax, zmin)), Expression('List', Expression('List', xmin, ymin, zmax), Expression('List', xmin, ymax, zmax), Expression('List', xmax, ymax, zmax)), Expression('List', Expression('List', xmin, ymin, zmax), Expression('List', xmax, ymin, zmax), Expression('List', xmax, ymax, zmax)), ] return Expression('Polygon', Expression('List', *polygons))
def apply_multiplevariable(self, f, vars, evaluation): 'Minimize[f_?NotListQ, vars_?ListQ]' head_name = vars.get_head_name() vars_or = vars vars = vars.leaves for var in vars: if ((var.is_atom() and not var.is_symbol()) or # noqa head_name in ('System`Plus', 'System`Times', 'System`Power') or 'System`Constant' in var.get_attributes(evaluation.definitions)): evaluation.message('Minimize', 'ivar', vars_or) return vars_sympy = [var.to_sympy() for var in vars] sympy_f = f.to_sympy() jacobian = [sympy.diff(sympy_f, x) for x in vars_sympy] hessian = sympy.Matrix([[sympy.diff(deriv, x) for x in vars_sympy] for deriv in jacobian]) candidates_tmp = sympy.solve(jacobian, vars_sympy, dict=True) candidates = [] for candidate in candidates_tmp: if len(candidate) != len(vars_sympy): for variable in candidate: for i in range(len(candidate), len(vars_sympy)): candidate[variable] = candidate[variable].subs( {vars_sympy[i]: 1}) for i in range(len(candidate), len(vars_sympy)): candidate[vars_sympy[i]] = 1 candidates.append(candidate) minimum_list = [] for candidate in candidates: eigenvals = hessian.subs(candidate).eigenvals() positives_eigenvalues = 0 negatives_eigenvalues = 0 for val in eigenvals: if val.is_real: if val < 0: negatives_eigenvalues += 1 elif val >= 0: positives_eigenvalues += 1 if positives_eigenvalues + negatives_eigenvalues != len(eigenvals): continue if positives_eigenvalues == len(eigenvals): minimum_list.append(candidate) return Expression( 'List', *(Expression('List', from_sympy( sympy_f.subs(minimum).simplify()), [ Expression('Rule', from_sympy(list(minimum.keys())[i]), from_sympy(list(minimum.values())[i])) for i in range(len(vars_sympy)) ]) for minimum in minimum_list))
class Evaluation(object): def __init__(self, input=None, definitions=None, timeout=None, out_callback=None, format='text', catch_interrupt=True): from mathics.core.definitions import Definitions if definitions is None: definitions = Definitions() self.definitions = definitions self.recursion_depth = 0 self.timeout = False self.stopped = False self.out = [] self.out_callback = out_callback self.listeners = {} self.options = None self.quiet_all = False self.quiet_messages = set() self.format = format queries = [] last_parse_error = None if input is not None: from mathics.core.parser import parse, TranslateError lines = input.splitlines() query = '' for line in lines: if line: query += line try: expression = parse(query, self.definitions) if expression is not None: queries.append(expression) query = '' last_parse_error = None except TranslateError, exc: last_parse_error = exc else: query += ' ' self.results = [] for query in queries: self.recursion_depth = 0 self.timeout = False self.stopped = False from mathics.core.expression import Symbol, Expression, Integer from mathics.core.rules import Rule line_no = self.get_config_value('$Line', 0) line_no += 1 self.definitions.set_ownvalue('$Line', Integer(line_no)) history_length = self.get_config_value('$HistoryLength', 100) if history_length is None or history_length > 100: history_length = 100 def evaluate(): if history_length > 0: self.definitions.add_rule( 'In', Rule(Expression('In', line_no), query)) result = query.evaluate(self) if history_length > 0: stored_result = self.get_stored_result(result) self.definitions.add_rule( 'Out', Rule(Expression('Out', line_no), stored_result)) if result != Symbol('Null'): return self.format_output(result) else: return None try: result = None exc_result = None try: if timeout is None: result = evaluate() else: with interruptingcow.timeout(timeout, TimeoutInterrupt): result = evaluate() except KeyboardInterrupt: if catch_interrupt: exc_result = Symbol('$Aborted') else: raise except ValueError, exc: text = unicode(exc) if (text == 'mpz.pow outrageous exponent' or # noqa text == 'mpq.pow outrageous exp num'): self.message('General', 'ovfl') exc_result = Expression('Overflow') else: raise except OverflowError: self.message('General', 'ovfl') exc_result = Expression('Overflow') except BreakInterrupt: self.message('Break', 'nofdw') exc_result = Expression('Hold', Expression('Break')) except ContinueInterrupt: self.message('Continue', 'nofdw') exc_result = Expression('Hold', Expression('Continue')) except TimeoutInterrupt: self.stopped = False self.timeout = True self.message('General', 'timeout') exc_result = Symbol('$Aborted') except AbortInterrupt: # , error: exc_result = Symbol('$Aborted') if exc_result is not None: self.recursion_depth = 0 result = self.format_output(exc_result) self.results.append(Result(self.out, result, line_no)) self.out = [] finally:
def apply(self, eqn, y, x, evaluation): 'DSolve[eqn_, y_, x_]' if eqn.has_form('List', eqn): # TODO: Try and solve BVPs using Solve or something analagous OR # add this functonality to sympy. evaluation.message('DSolve', 'symsys') return if eqn.get_head_name() != 'System`Equal': evaluation.message('DSolve', 'deqn', eqn) return # FIXME: This code is duplicated in calculus.py if ((x.is_atom() and not x.is_symbol()) or # nopep8 x.get_head_name() in ('System`Plus', 'System`Times', 'System`Power') or 'System`Constant' in x.get_attributes(evaluation.definitions)): evaluation.message('DSolve', 'dsvar') return # Fixes pathalogical DSolve[y''[x] == y[x], y, x] try: y.leaves function_form = None func = y except AttributeError: func = Expression(y, x) function_form = Expression('List', x) if func.is_atom(): evaluation.message('DSolve', 'dsfun', y) return if len(func.leaves) != 1: evaluation.message('DSolve', 'symmua') return if x not in func.leaves: evaluation.message('DSolve', 'deqx') return left, right = eqn.leaves eqn = Expression('Plus', left, Expression( 'Times', -1, right)).evaluate(evaluation) sym_eq = eqn.to_sympy(converted_functions=set([func.get_head_name()])) sym_x = sympy.symbols(str(sympy_symbol_prefix + x.name)) sym_func = sympy.Function(str( sympy_symbol_prefix + func.get_head_name()))(sym_x) try: sym_result = sympy.dsolve(sym_eq, sym_func) except ValueError: evaluation.message('DSolve', 'symimp') return except NotImplementedError: evaluation.message('DSolve', 'symimp') return except TypeError: # Sympy bug #9446 evaluation.message('DSolve', 'litarg', eqn) return except AttributeError: evaluation.message('DSolve', 'litarg', eqn) return except KeyError: evaluation.message('DSolve', 'litarg', eqn) return else: if not isinstance(sym_result, list): sym_result = [sym_result] if function_form is None: return Expression('List', *[ Expression( 'List', Expression('Rule', *from_sympy(soln).leaves)) for soln in sym_result]) else: return Expression('List', *[ Expression('List', Expression('Rule', y, Expression( 'Function', function_form, *from_sympy(soln).leaves[1:]))) for soln in sym_result])
def callback(level): if level.is_atom(): return level else: return Expression(f, *level.leaves)
def apply(self, eqns, a, n, evaluation): "RSolve[eqns_, a_, n_]" # TODO: Do this with rules? if not eqns.has_form("List", None): eqns = Expression("List", eqns) if len(eqns.leaves) == 0: return for eqn in eqns.leaves: if eqn.get_head_name() != "System`Equal": evaluation.message("RSolve", "deqn", eqn) return if ( (n.is_atom() and not n.is_symbol()) or n.get_head_name() in ("System`Plus", "System`Times", "System`Power") or "System`Constant" in n.get_attributes(evaluation.definitions) ): # TODO: Factor out this check for dsvar into a separate # function. DSolve uses this too. evaluation.message("RSolve", "dsvar") return try: a.leaves function_form = None func = a except AttributeError: func = Expression(a, n) function_form = Expression("List", n) if func.is_atom() or len(func.leaves) != 1: evaluation.message("RSolve", "dsfun", a) if n not in func.leaves: evaluation.message("DSolve", "deqx") # Seperate relations from conditions conditions = {} def is_relation(eqn): left, right = eqn.leaves for l, r in [(left, right), (right, left)]: if ( left.get_head_name() == func.get_head_name() and len(left.leaves) == 1 # noqa and isinstance(l.leaves[0].to_python(), int) and r.is_numeric() ): r_sympy = r.to_sympy() if r_sympy is None: raise ValueError conditions[l.leaves[0].to_python()] = r_sympy return False return True # evaluate is_relation on all leaves to store conditions try: relations = [leaf for leaf in eqns.leaves if is_relation(leaf)] except ValueError: return relation = relations[0] left, right = relation.leaves relation = Expression("Plus", left, Expression("Times", -1, right)).evaluate( evaluation ) sym_eq = relation.to_sympy(converted_functions=set([func.get_head_name()])) if sym_eq is None: return sym_n = sympy.core.symbols(str(sympy_symbol_prefix + n.name)) sym_func = sympy.Function(str(sympy_symbol_prefix + func.get_head_name()))( sym_n ) sym_conds = {} for cond in conditions: sym_conds[ sympy.Function(str(sympy_symbol_prefix + func.get_head_name()))(cond) ] = conditions[cond] try: # Sympy raises error when given empty conditions. Fixed in # upcomming sympy release. if sym_conds != {}: sym_result = sympy.rsolve(sym_eq, sym_func, sym_conds) else: sym_result = sympy.rsolve(sym_eq, sym_func) if not isinstance(sym_result, list): sym_result = [sym_result] except ValueError: return if function_form is None: return Expression( "List", *[ Expression("List", Expression("Rule", a, from_sympy(soln))) for soln in sym_result ] ) else: return Expression( "List", *[ Expression( "List", Expression( "Rule", a, Expression("Function", function_form, from_sympy(soln)), ), ) for soln in sym_result ] )
def callback(level, pos): return Expression(f, level, Expression('List', *(Integer(p) for p in pos)))
def diff(evaluation): return Expression('D', f, x).evaluate(evaluation)
def summand(i): return Expression(f, get_part(list1, i_cur + [i]), get_part(list2, [i] + j_cur))
def options_to_rules(options, filter=None): items = sorted(options.items()) if filter: items = [(name, value) for name, value in items if strip_context(name) in filter.keys()] return [Expression('Rule', Symbol(name), value) for name, value in items]