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

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

""" 

Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>`` 

  

AUTHORS: 

  

- Burcin Erocal 

- Martin Albrecht 

""" 

############################################################################### 

# SAGE: Open Source Mathematical Software 

# Copyright (C) 2011 Burcin Erocal <burcin@erocal.org> 

# Copyright (C) 2011 Martin Albrecht <martinralbrecht@googlemail.com> 

# Distributed under the terms of the GNU General Public License (GPL), 

# version 2 or any later version. The full text of the GPL is available at: 

# http://www.gnu.org/licenses/ 

############################################################################### 

  

  

from sage.rings.finite_rings.stdint cimport * 

  

from sage.libs.linbox.echelonform cimport BlasMatrixDouble as BlasMatrix 

from sage.libs.linbox.modular cimport ModDoubleField as ModField, ModDoubleFieldElement as ModFieldElement 

from sage.libs.linbox.echelonform cimport EchelonFormDomainDouble as EchelonFormDomain 

  

from sage.libs.linbox.fflas cimport ModDouble_fgemm as Mod_fgemm, ModDouble_fgemv as Mod_fgemv, \ 

ModDoubleDet as ModDet, \ 

ModDoubleRank as ModRank, ModDouble_echelon as Mod_echelon, \ 

ModDouble_applyp as Mod_applyp, \ 

ModDouble_MinPoly as Mod_MinPoly, \ 

ModDouble_CharPoly as Mod_CharPoly, \ 

ModDoublePolynomialRing as ModDensePolyRing,\ 

ModDoubleDensePolynomial as ModDensePoly 

  

# Limit for LinBox Modular<double> 

MAX_MODULUS = 2**23 

  

from sage.rings.finite_rings.integer_mod cimport IntegerMod_int64 

  

include "matrix_modn_dense_template.pxi" 

  

  

cdef class Matrix_modn_dense_double(Matrix_modn_dense_template): 

r""" 

Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>`` 

  

These are matrices with integer entries mod ``n`` represented as 

floating-point numbers in a 64-bit word for use with LinBox routines. 

This allows for ``n`` up to `2^{23}`. The analogous 

``Matrix_modn_dense_float`` class is used for smaller moduli. 

  

Routines here are for the most basic access, see the 

`matrix_modn_dense_template.pxi` file for higher-level routines. 

""" 

  

def __cinit__(self): 

""" 

The Cython constructor 

  

TESTS:: 

  

sage: A = random_matrix(IntegerModRing(2^16), 4, 4) 

sage: type(A[0,0]) 

<type 'sage.rings.finite_rings.integer_mod.IntegerMod_int64'> 

""" 

self._get_template = self._base_ring.zero() 

# note that INTEGER_MOD_INT32_LIMIT is ceil(sqrt(2^31-1)) < 2^23 

self._fits_int32 = ((<Matrix_modn_dense_template>self).p <= INTEGER_MOD_INT32_LIMIT) 

  

cdef set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value): 

r""" 

Set the (i,j) entry of self to the int value. 

  

EXAMPLES:: 

  

sage: A = random_matrix(GF(3016963), 4, 4); A 

[ 220081 2824836 765701 2282256] 

[1795330 767112 2967421 1373921] 

[2757699 1142917 2720973 2877160] 

[1674049 1341486 2641133 2173280] 

sage: A[0,0] = 220082r; A 

[ 220082 2824836 765701 2282256] 

[1795330 767112 2967421 1373921] 

[2757699 1142917 2720973 2877160] 

[1674049 1341486 2641133 2173280] 

sage: a = A[0,0]; a 

220082 

sage: ~a 

2859358 

  

sage: A = random_matrix(Integers(5099106), 4, 4); A 

[2629491 1237101 2033003 3788106] 

[4649912 1157595 4928315 4382585] 

[4252686 978867 2601478 1759921] 

[1303120 1860486 3405811 2203284] 

sage: A[0,0] = 220082r; A 

[ 220082 1237101 2033003 3788106] 

[4649912 1157595 4928315 4382585] 

[4252686 978867 2601478 1759921] 

[1303120 1860486 3405811 2203284] 

sage: a = A[0,0]; a 

220082 

sage: a*a 

4777936 

""" 

self._matrix[i][j] = <double>value 

  

cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, x): 

r""" 

Set the (i,j) entry with no bounds-checking, or any other checks. 

  

Assumes that `x` is in the base ring. 

  

EXAMPLES:: 

  

sage: A = random_matrix(GF(3016963), 4, 4); A 

[ 220081 2824836 765701 2282256] 

[1795330 767112 2967421 1373921] 

[2757699 1142917 2720973 2877160] 

[1674049 1341486 2641133 2173280] 

sage: K = A.base_ring() 

sage: A[0,0] = K(220082); A 

[ 220082 2824836 765701 2282256] 

[1795330 767112 2967421 1373921] 

[2757699 1142917 2720973 2877160] 

[1674049 1341486 2641133 2173280] 

sage: a = A[0,0]; a 

220082 

sage: ~a 

2859358 

  

sage: A = random_matrix(Integers(5099106), 4, 4); A 

[2629491 1237101 2033003 3788106] 

[4649912 1157595 4928315 4382585] 

[4252686 978867 2601478 1759921] 

[1303120 1860486 3405811 2203284] 

sage: K = A.base_ring() 

sage: A[0,0] = K(220081) 

sage: a = A[0,0]; a 

220081 

sage: a*a 

4337773 

""" 

if (<Matrix_modn_dense_double>self)._fits_int32: 

self._matrix[i][j] = <double>(<IntegerMod_int>x).ivalue 

else: 

self._matrix[i][j] = <double>(<IntegerMod_int64>x).ivalue 

  

cdef IntegerMod_abstract get_unsafe(self, Py_ssize_t i, Py_ssize_t j): 

r""" 

Return the (i,j) entry with no bounds-checking. 

  

OUTPUT: 

  

A :class:`sage.rings.finite_rings.integer_mod.IntegerMod_int` 

or 

:class:`sage.rings.finite_rings.integer_mod.IntegerMod_int64` 

object, depending on the modulus. 

  

EXAMPLES:: 

  

sage: A = random_matrix(GF(3016963), 4, 4); A 

[ 220081 2824836 765701 2282256] 

[1795330 767112 2967421 1373921] 

[2757699 1142917 2720973 2877160] 

[1674049 1341486 2641133 2173280] 

sage: a = A[0,0]; a 

220081 

sage: ~a 

697224 

sage: K = A.base_ring() 

sage: ~K(220081) 

697224 

  

sage: A = random_matrix(Integers(5099106), 4, 4); A 

[2629491 1237101 2033003 3788106] 

[4649912 1157595 4928315 4382585] 

[4252686 978867 2601478 1759921] 

[1303120 1860486 3405811 2203284] 

sage: a = A[0,1]; a 

1237101 

sage: a*a 

3803997 

sage: K = A.base_ring() 

sage: K(1237101)^2 

3803997 

""" 

cdef Matrix_modn_dense_double _self = <Matrix_modn_dense_double>self 

cdef double result = (<Matrix_modn_dense_template>self)._matrix[i][j] 

if _self._fits_int32: 

return (<IntegerMod_int>_self._get_template)._new_c(<int_fast32_t>result) 

else: 

return (<IntegerMod_int64>_self._get_template)._new_c(<int_fast64_t>result)