Mathics icon indicating copy to clipboard operation
Mathics copied to clipboard

Mathics crashes when trying to solve a differention equation whose result can't be expressed as an explicit function

Open GarkGarcia opened this issue 5 years ago • 0 comments

The solutions for the following differential equation can't be easily expressed as explicit functions:

img-e18884b07ac6daf7

The solutions to this equation are given implicitly by the equation:

img-d7b2801affbe08d3

So, here's the bug:

In[1]:= DSolve[y'[x] ==  1 + Sqrt[x^2 + y[x]^2] / x, y[x], x
Integrate::ilim: Invalid integration variable or limit(s).
Integrate::ilim: Invalid integration variable or limit(s).
 File "/home/pablo/.local/bin/mathicsscript", line 293, in <module>
    main()
  File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/pablo/.local/bin/mathicsscript", line 276, in main
    result = evaluation.evaluate(query, timeout=settings.TIMEOUT)
  File "/home/pablo/Documents/Mathics/mathics/core/evaluation.py", line 291, in evaluate
    result = run_with_timeout_and_stack(evaluate, timeout)
  File "/home/pablo/Documents/Mathics/mathics/core/evaluation.py", line 95, in run_with_timeout_and_stack
    return request()
  File "/home/pablo/Documents/Mathics/mathics/core/evaluation.py", line 269, in evaluate
    result = query.evaluate(self)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
    expr, reevaluate = expr.evaluate_next(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
    eval_range(range(len(leaves)))
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
    leaves[index] = leaf.evaluate(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
    expr, reevaluate = expr.evaluate_next(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
    eval_range(range(len(leaves)))
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
    leaves[index] = leaf.evaluate(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
    expr, reevaluate = expr.evaluate_next(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
    eval_range(range(len(leaves)))
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
    leaves[index] = leaf.evaluate(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
    expr, reevaluate = expr.evaluate_next(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
    eval_range(range(len(leaves)))
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
    leaves[index] = leaf.evaluate(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
    expr, reevaluate = expr.evaluate_next(evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1222, in evaluate_next
    result = rule.apply(new, evaluation, fully=False)
  File "/home/pablo/Documents/Mathics/mathics/core/rules.py", line 64, in apply
    yield_match, expression, {}, evaluation, fully=fully)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 239, in match
    yield_head, expression.get_head(), vars, evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 137, in match
    yield_func(vars, None)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 231, in yield_head
    yield_choice, expression, attributes, head_vars)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 358, in get_pre_choices
    yield_func(vars)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 220, in yield_choice
    wrap_oneid=expression.get_head_name() != 'System`MakeBoxes')
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 519, in match_leaf
    include_flattened=include_flattened)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 379, in get_wrappings
    yield_func(items[0])
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 515, in yield_wrapping
    leaf_count=leaf_count, wrap_oneid=wrap_oneid)
  File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 770, in match
    self.pattern.match(yield_func, expression, new_vars, evaluation)
  File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 955, in match
    yield_func(vars, None)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 507, in match_yield
    leaf_count=leaf_count, wrap_oneid=wrap_oneid)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 519, in match_leaf
    include_flattened=include_flattened)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 379, in get_wrappings
    yield_func(items[0])
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 515, in yield_wrapping
    leaf_count=leaf_count, wrap_oneid=wrap_oneid)
  File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 770, in match
    self.pattern.match(yield_func, expression, new_vars, evaluation)
  File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 955, in match
    yield_func(vars, None)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 510, in match_yield
    yield_func(new_vars, items_rest)
  File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 499, in leaf_yield
    (list(chain(rest_expression[0], items_rest[0])), next_rest[1]))
  File "/home/pablo/Documents/Mathics/mathics/core/rules.py", line 40, in yield_match
    new_expression = self.do_replace(expression, vars, options, evaluation)
  File "/home/pablo/Documents/Mathics/mathics/core/rules.py", line 129, in do_replace
    return self.function(evaluation=evaluation, **vars_noctx)
  File "/home/pablo/Documents/Mathics/mathics/builtin/arithmetic.py", line 847, in apply_check
    result = self.apply(Expression('Sequence', x, y), evaluation)
  File "/home/pablo/Documents/Mathics/mathics/builtin/arithmetic.py", line 50, in apply
    result = Expression(self.get_name(), *args).to_sympy()
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
    sympy_expr = builtin.to_sympy(self, **kwargs)
  File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in to_sympy
    sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
  File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in <listcomp>
    sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
    sympy_expr = builtin.to_sympy(self, **kwargs)
  File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in to_sympy
    sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
  File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in <listcomp>
    sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
    sympy_expr = builtin.to_sympy(self, **kwargs)
  File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in to_sympy
    sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
  File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in <listcomp>
    sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
  File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
    sympy_expr = builtin.to_sympy(self, **kwargs)
  File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 472, in to_sympy
    return sympy_function(*sympy_args)
  File "/home/pablo/.local/lib/python3.6/site-packages/sympy/integrals/integrals.py", line 87, in __new__
    obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions)
  File "/home/pablo/.local/lib/python3.6/site-packages/sympy/concrete/expr_with_limits.py", line 494, in __new__
    pre = _common_new(cls, function, *symbols, **assumptions)
  File "/home/pablo/.local/lib/python3.6/site-packages/sympy/concrete/expr_with_limits.py", line 48, in _common_new
    limits, orientation = _process_limits(*symbols)
  File "/home/pablo/.local/lib/python3.6/site-packages/sympy/concrete/expr_with_limits.py", line 156, in _process_limits
    raise ValueError('Invalid limits given: %s' % str(symbols))
ValueError: Invalid limits given: (SympyExpression(_Mathics_User_System`List, _u2, _Mathics_User_Global`x/SympyExpression(_Mathics_User_Global`y, _Mathics_User_Global`x)),)

By digging around a bit, I was able to figure out that it's a bug in SymPy. After processing the differential equation, SymPy returns this:

[Eq(_Mathics_User_Global`y(_Mathics_User_Global`x), C1*exp(-Integral(sqrt(_u2**2 + 1)/(_u2*(_u2 + sqrt(_u2**2 + 1) - 1)), (_u2, _Mathics_User_Global`x/_Mathics_User_Global`y(_Mathics_User_Global`x))) - Integral(1/(_u2 + sqrt(_u2**2 + 1) - 1), (_u2, _Mathics_User_Global`x/_Mathics_User_Global`y(_Mathics_User_Global`x)))))]

This is malformed output. First of all, it mentions a variable called _u2 (which I assume is a temporary substitution variable _u2 = y/x SymPy uses internally). Also, the expression Integral(..., (_u2, y/x)) doesn't make much sense.

GarkGarcia avatar Oct 07 '20 23:10 GarkGarcia