3

Using sympy how do I keep fractions separate from variables

Mul(Fraction(3,5), Pow(K, Integer(2)))


     2          
  3⋅K         
 ──── 
   5          

to 

               
 3  2      
 ─ K
 5 

I know this simplified version is not too bad, but when i have really big equations, it gets messy

Rob
  • 31
  • 2

2 Answers2

1

I'm not very familiar with pretty printing or LaTeX printing but I managed to come up with something. Put UnevaluatedExpr in each of the arguments of Mul:

from sympy import *
from fractions import Fraction

K = symbols("K")
expr1 = Mul(UnevaluatedExpr(Fraction(3,5)), UnevaluatedExpr(Pow(K, Integer(2))))
expr2 = Mul(UnevaluatedExpr(pi/5), UnevaluatedExpr(Pow(K, Integer(2))))
expr3 = ((UnevaluatedExpr(S(1)*3123456789/512345679) * UnevaluatedExpr(Pow(K, Integer(2)))))
pprint(expr1)
pprint(expr2)
pprint(expr3)

Produces:

     2
3/5⋅K 

π  2
─⋅K 
5   

1041152263  2
──────────⋅K 
170781893   

I couldn't find a way to make it print a stacked fraction for the slashed fraction 3/5. Longer fractions seem to work though. If you are printing in LaTeX however, the documentation suggests something like latex(expr1, fold_frac_powers=False) to correct this.

Too bad I couldn't find an elegant solution like putting init_printing(div_stack_symbols=False) at the top of the document.

Chris du Plessis
  • 1,250
  • 7
  • 13
0

To elaborate on Maelstrom's Answer, you need to do 2 things to make this work like you want:

  1. Create the separate fraction you want as its own expression.
  2. Prevent the numerator or denominator from being modified when the expression is combined with other expressions.

What Maelstrom showed will work, but it's much more complicated than what's actually needed. Here's a much cleaner solution:

from sympy import *

K = symbols("K")

# Step 1: make the fraction

# This seems to be a weird workaround to prevent fractions from being broken
# apart. See the note after this code block.
lh_frac = UnevaluatedExpr(3) / 5

# Step 2: prevent the fraction from being modified

# Creating a new multiplication expression will normally modify the involved
# expressions as sympy sees fit. Setting evaluate to False prevents that.
expr = Mul(lh_frac , Pow(K, 2), evaluate=False)

pprint(expr)

gives:

3  2
-*K 
5   

Important Note:

Doing lh_frac = UnevaluatedExpr(3) / 5 is not how fractions involving 2 literal numbers should typically be created. Normally, you would do:

lh_frac = Rational(3, 5)

as shown in the sympy docs. However, that gives undesirable output for our use case right now:

   2
3*K 
----
 5  

This outcome is surprising to me; setting evaluate to False inside Mul should be sufficient to do what we want. I have an open question about this.

drmuelr
  • 955
  • 1
  • 13
  • 30