Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

"""A module providing information about the necessity of brackets""" 

 

from __future__ import print_function, division 

 

from sympy.core.function import _coeff_isneg 

 

# Default precedence values for some basic types 

PRECEDENCE = { 

"Lambda": 1, 

"Xor": 10, 

"Or": 20, 

"And": 30, 

"Relational": 35, 

"Add": 40, 

"Mul": 50, 

"Pow": 60, 

"Func": 70, 

"Not": 100, 

"Atom": 1000 

} 

 

# A dictionary assigning precedence values to certain classes. These values are 

# treated like they were inherited, so not every single class has to be named 

# here. 

PRECEDENCE_VALUES = { 

"Equivalent": PRECEDENCE["Xor"], 

"Xor": PRECEDENCE["Xor"], 

"Implies": PRECEDENCE["Xor"], 

"Or": PRECEDENCE["Or"], 

"And": PRECEDENCE["And"], 

"Add": PRECEDENCE["Add"], 

"Pow": PRECEDENCE["Pow"], 

"Relational": PRECEDENCE["Relational"], 

"Sub": PRECEDENCE["Add"], 

"Not": PRECEDENCE["Not"], 

"Function" : PRECEDENCE["Func"], 

"NegativeInfinity": PRECEDENCE["Add"], 

"MatAdd": PRECEDENCE["Add"], 

"MatMul": PRECEDENCE["Mul"], 

"MatPow": PRECEDENCE["Pow"], 

"HadamardProduct": PRECEDENCE["Mul"] 

} 

 

# Sometimes it's not enough to assign a fixed precedence value to a 

# class. Then a function can be inserted in this dictionary that takes 

# an instance of this class as argument and returns the appropriate 

# precedence value. 

 

# Precedence functions 

 

 

def precedence_Mul(item): 

if _coeff_isneg(item): 

return PRECEDENCE["Add"] 

return PRECEDENCE["Mul"] 

 

 

def precedence_Rational(item): 

if item.p < 0: 

return PRECEDENCE["Add"] 

return PRECEDENCE["Mul"] 

 

 

def precedence_Integer(item): 

if item.p < 0: 

return PRECEDENCE["Add"] 

return PRECEDENCE["Atom"] 

 

 

def precedence_Float(item): 

if item < 0: 

return PRECEDENCE["Add"] 

return PRECEDENCE["Atom"] 

 

 

def precedence_PolyElement(item): 

if item.is_generator: 

return PRECEDENCE["Atom"] 

elif item.is_ground: 

return precedence(item.coeff(1)) 

elif item.is_term: 

return PRECEDENCE["Mul"] 

else: 

return PRECEDENCE["Add"] 

 

 

def precedence_FracElement(item): 

if item.denom == 1: 

return precedence_PolyElement(item.numer) 

else: 

return PRECEDENCE["Mul"] 

 

 

PRECEDENCE_FUNCTIONS = { 

"Integer": precedence_Integer, 

"Mul": precedence_Mul, 

"Rational": precedence_Rational, 

"Float": precedence_Float, 

"PolyElement": precedence_PolyElement, 

"FracElement": precedence_FracElement, 

} 

 

 

def precedence(item): 

""" 

Returns the precedence of a given object. 

""" 

if hasattr(item, "precedence"): 

return item.precedence 

try: 

mro = item.__class__.__mro__ 

except AttributeError: 

return PRECEDENCE["Atom"] 

for i in mro: 

n = i.__name__ 

if n in PRECEDENCE_FUNCTIONS: 

return PRECEDENCE_FUNCTIONS[n](item) 

elif n in PRECEDENCE_VALUES: 

return PRECEDENCE_VALUES[n] 

return PRECEDENCE["Atom"] 

 

 

def precedence_traditional(item): 

""" 

Returns the precedence of a given object according to the traditional rules 

of mathematics. This is the precedence for the LaTeX and pretty printer. 

""" 

# Integral, Sum, Product, Limit have the precedence of Mul in LaTeX, 

# the precedence of Atom for other printers: 

from sympy import Integral, Sum, Product, Limit, Derivative 

 

if isinstance(item, (Integral, Sum, Product, Limit, Derivative)): 

return PRECEDENCE["Mul"] 

else: 

return precedence(item)