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

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

""" 

Local Density Interfaces 

""" 

## // This is needed in the filter for primitivity... 

## #include "../max-min.h" 

 

 

from sage.arith.all import valuation 

from sage.rings.rational_field import QQ 

 

 

 

 

 

def local_density(self, p, m): 

""" 

Gives the local density -- should be called by the user. =) 

 

NOTE: This screens for imprimitive forms, and puts the quadratic 

form in local normal form, which is a *requirement* of the 

routines performing the computations! 

 

INPUT: 

 

`p` -- a prime number > 0 

`m` -- an integer 

 

OUTPUT: 

 

a rational number 

 

EXAMPLES:: 

 

sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) ## NOTE: This is already in local normal form for *all* primes p! 

sage: Q.local_density(p=2, m=1) 

1 

sage: Q.local_density(p=3, m=1) 

8/9 

sage: Q.local_density(p=5, m=1) 

24/25 

sage: Q.local_density(p=7, m=1) 

48/49 

sage: Q.local_density(p=11, m=1) 

120/121 

 

""" 

n = self.dim() 

if (n == 0): 

raise TypeError("Oops! We currently don't handle 0-dim'l forms. =(") 

 

## Find the local normal form and p-scale of Q -- Note: This uses the valuation ordering of local_normal_form. 

## TO DO: Write a separate p-scale and p-norm routines! 

Q_local = self.local_normal_form(p) 

if n == 1: 

p_valuation = valuation(Q_local[0,0], p) 

else: 

p_valuation = min(valuation(Q_local[0,0], p), valuation(Q_local[0,1], p)) 

 

## If m is less p-divisible than the matrix, return zero 

if ((m != 0) and (valuation(m,p) < p_valuation)): ## Note: The (m != 0) condition protects taking the valuation of zero. 

return QQ(0) 

 

 

## If the form is imprimitive, rescale it and call the local density routine 

p_adjustment = QQ(1) / p**p_valuation 

m_prim = QQ(m) / p**p_valuation 

Q_prim = Q_local.scale_by_factor(p_adjustment) 

 

## Return the densities for the reduced problem 

return Q_prim.local_density_congruence(p, m_prim) 

 

 

 

 

def local_primitive_density(self, p, m): 

""" 

Gives the local primitive density -- should be called by the user. =) 

 

NOTE: This screens for imprimitive forms, and puts the 

quadratic form in local normal form, which is a *requirement* of 

the routines performing the computations! 

 

INPUT: 

 

`p` -- a prime number > 0 

`m` -- an integer 

 

OUTPUT: 

 

a rational number 

 

EXAMPLES:: 

 

sage: Q = QuadraticForm(ZZ, 4, range(10)) 

sage: Q[0,0] = 5 

sage: Q[1,1] = 10 

sage: Q[2,2] = 15 

sage: Q[3,3] = 20 

sage: Q 

Quadratic form in 4 variables over Integer Ring with coefficients: 

[ 5 1 2 3 ] 

[ * 10 5 6 ] 

[ * * 15 8 ] 

[ * * * 20 ] 

sage: Q.theta_series(20) 

1 + 2*q^5 + 2*q^10 + 2*q^14 + 2*q^15 + 2*q^16 + 2*q^18 + O(q^20) 

sage: Q.local_normal_form(2) 

Quadratic form in 4 variables over Integer Ring with coefficients: 

[ 0 1 0 0 ] 

[ * 0 0 0 ] 

[ * * 0 1 ] 

[ * * * 0 ] 

 

sage: Q.local_primitive_density(2, 1) 

3/4 

sage: Q.local_primitive_density(5, 1) 

24/25 

 

sage: Q.local_primitive_density(2, 5) 

3/4 

sage: Q.local_density(2, 5) 

3/4 

 

""" 

n = self.dim() 

if (n == 0): 

raise TypeError("Oops! We currently don't handle 0-dim'l forms. =(") 

 

## Find the local normal form and p-scale of Q -- Note: This uses the valuation ordering of local_normal_form. 

## TO DO: Write a separate p-scale and p-norm routines! 

Q_local = self.local_normal_form(p) 

if n == 1: 

p_valuation = valuation(Q_local[0,0], p) 

else: 

p_valuation = min(valuation(Q_local[0,0], p), valuation(Q_local[0,1], p)) 

 

 

## If m is less p-divisible than the matrix, return zero 

if ((m != 0) and (valuation(m,p) < p_valuation)): ## Note: The (m != 0) condition protects taking the valuation of zero. 

return QQ(0) 

 

 

## If the form is imprimitive, rescale it and call the local density routine 

p_adjustment = QQ(1) / p**p_valuation 

m_prim = QQ(m) / p**p_valuation 

Q_prim = Q_local.scale_by_factor(p_adjustment) 

 

## Return the densities for the reduced problem 

return Q_prim.local_primitive_density_congruence(p, m_prim)