1

I'm using sympy to do a nonlinear solve over a set of power laws, and I end up with a bunch of solutions like

20394*sqrt(6)*x**(2/3)*y**(1/4)

I want to collapse the numerical coefficients while leaving the rational nature of the exponents exposed, i.e. I want my code to output

49954.8938143201*x**(2/3)*y**(1/4)

However, when I use evalf(), I get

49954.8938143201*x**0.666666666666667*y**0.25

Is there any way to ask sympy to not evaluate exponents, or even just to extract the non-symbolic part of the answer so I can create my own print function that formats output in the way I want?

user2275987
  • 129
  • 11

1 Answers1

2

One approach is to pick all Mul and Add subexpressions, separate their arguments into numeric and symbolic (based on whether any symbol is contained), and numerically evaluate the part with numeric arguments.

expr = 20394*sqrt(6)*x**(S(2)/3) + 3*log(3)*y**(S(3)/2) - 3*sqrt(7) + (3+sqrt(2))*x*y
eval_dict = {}
for a in expr.atoms(Mul, Add):
    numeric = [arg for arg in a.args if not arg.has(Symbol)]
    symbolic = [arg for arg in a.args if arg.has(Symbol)]
    eval_dict[a] = a.func(a.func(*numeric).evalf(), a.func(*symbolic)) 
print(expr.subs(eval_dict))

This prints

49954.8938143201*x**(2/3) + 4.41421356237309*x*y + 3.29583686600433*y**(3/2) - 7.93725393319377

The rational exponents escape numeric evaluation, being instances of Rational.

  • Sorry, my question as stated was not sufficiently general -- I have multiple symbolic factors apart from the numerical coefficient. I tried to adapt your method to this case but I figure out how to use as_independent over two symbolic variables. – user2275987 Feb 22 '18 at 19:00
  • 1
    Okay, I rewrote the script and included a more complicated example with two variables. –  Feb 22 '18 at 22:17