passagemath-ntl 10.8.1a1__cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. passagemath_ntl/__init__.py +3 -0
  2. passagemath_ntl-10.8.1a1.dist-info/METADATA +121 -0
  3. passagemath_ntl-10.8.1a1.dist-info/RECORD +162 -0
  4. passagemath_ntl-10.8.1a1.dist-info/WHEEL +6 -0
  5. passagemath_ntl-10.8.1a1.dist-info/top_level.txt +3 -0
  6. passagemath_ntl.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  7. passagemath_ntl.libs/libgmp-6e109695.so.10.5.0 +0 -0
  8. passagemath_ntl.libs/libmpfi-bcd96d8d.so.0.0.0 +0 -0
  9. passagemath_ntl.libs/libmpfr-104d25bb.so.6.2.2 +0 -0
  10. passagemath_ntl.libs/libntl-bacfd860.so.45.0.0 +0 -0
  11. sage/all__sagemath_ntl.py +7 -0
  12. sage/libs/all__sagemath_ntl.py +3 -0
  13. sage/libs/mpfi/__init__.pxd +287 -0
  14. sage/libs/mpfi/types.pxd +10 -0
  15. sage/libs/ntl/GF2.pxd +18 -0
  16. sage/libs/ntl/GF2E.pxd +28 -0
  17. sage/libs/ntl/GF2EX.pxd +12 -0
  18. sage/libs/ntl/GF2X.pxd +81 -0
  19. sage/libs/ntl/ZZ.pxd +93 -0
  20. sage/libs/ntl/ZZX.pxd +85 -0
  21. sage/libs/ntl/ZZ_p.pxd +28 -0
  22. sage/libs/ntl/ZZ_pE.pxd +37 -0
  23. sage/libs/ntl/ZZ_pEX.pxd +106 -0
  24. sage/libs/ntl/ZZ_pX.pxd +122 -0
  25. sage/libs/ntl/__init__.py +4 -0
  26. sage/libs/ntl/all.py +72 -0
  27. sage/libs/ntl/conversion.pxd +106 -0
  28. sage/libs/ntl/convert.cpython-314t-x86_64-linux-gnu.so +0 -0
  29. sage/libs/ntl/convert.pxd +7 -0
  30. sage/libs/ntl/convert.pyx +38 -0
  31. sage/libs/ntl/decl.pxi +18 -0
  32. sage/libs/ntl/error.cpython-314t-x86_64-linux-gnu.so +0 -0
  33. sage/libs/ntl/error.pyx +63 -0
  34. sage/libs/ntl/lzz_p.pxd +20 -0
  35. sage/libs/ntl/lzz_pX.pxd +59 -0
  36. sage/libs/ntl/mat_GF2.pxd +30 -0
  37. sage/libs/ntl/mat_GF2E.pxd +30 -0
  38. sage/libs/ntl/mat_ZZ.pxd +59 -0
  39. sage/libs/ntl/misc.pxi +33 -0
  40. sage/libs/ntl/ntl_GF2.cpython-314t-x86_64-linux-gnu.so +0 -0
  41. sage/libs/ntl/ntl_GF2.pxd +5 -0
  42. sage/libs/ntl/ntl_GF2.pyx +281 -0
  43. sage/libs/ntl/ntl_GF2E.cpython-314t-x86_64-linux-gnu.so +0 -0
  44. sage/libs/ntl/ntl_GF2E.pxd +8 -0
  45. sage/libs/ntl/ntl_GF2E.pyx +488 -0
  46. sage/libs/ntl/ntl_GF2EContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  47. sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
  48. sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
  49. sage/libs/ntl/ntl_GF2EX.cpython-314t-x86_64-linux-gnu.so +0 -0
  50. sage/libs/ntl/ntl_GF2EX.pxd +10 -0
  51. sage/libs/ntl/ntl_GF2EX.pyx +251 -0
  52. sage/libs/ntl/ntl_GF2X.cpython-314t-x86_64-linux-gnu.so +0 -0
  53. sage/libs/ntl/ntl_GF2X.pxd +5 -0
  54. sage/libs/ntl/ntl_GF2X.pyx +771 -0
  55. sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
  56. sage/libs/ntl/ntl_ZZ.cpython-314t-x86_64-linux-gnu.so +0 -0
  57. sage/libs/ntl/ntl_ZZ.pxd +7 -0
  58. sage/libs/ntl/ntl_ZZ.pyx +541 -0
  59. sage/libs/ntl/ntl_ZZX.cpython-314t-x86_64-linux-gnu.so +0 -0
  60. sage/libs/ntl/ntl_ZZX.pxd +7 -0
  61. sage/libs/ntl/ntl_ZZX.pyx +1206 -0
  62. sage/libs/ntl/ntl_ZZ_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  63. sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
  64. sage/libs/ntl/ntl_ZZ_p.pyx +508 -0
  65. sage/libs/ntl/ntl_ZZ_pContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  66. sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
  67. sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
  68. sage/libs/ntl/ntl_ZZ_pE.cpython-314t-x86_64-linux-gnu.so +0 -0
  69. sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
  70. sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
  71. sage/libs/ntl/ntl_ZZ_pEContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  72. sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
  73. sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
  74. sage/libs/ntl/ntl_ZZ_pEX.cpython-314t-x86_64-linux-gnu.so +0 -0
  75. sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
  76. sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
  77. sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
  78. sage/libs/ntl/ntl_ZZ_pX.cpython-314t-x86_64-linux-gnu.so +0 -0
  79. sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
  80. sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
  81. sage/libs/ntl/ntl_lzz_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  82. sage/libs/ntl/ntl_lzz_p.pxd +8 -0
  83. sage/libs/ntl/ntl_lzz_p.pyx +440 -0
  84. sage/libs/ntl/ntl_lzz_pContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  85. sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
  86. sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
  87. sage/libs/ntl/ntl_lzz_pX.cpython-314t-x86_64-linux-gnu.so +0 -0
  88. sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
  89. sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
  90. sage/libs/ntl/ntl_mat_GF2.cpython-314t-x86_64-linux-gnu.so +0 -0
  91. sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
  92. sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
  93. sage/libs/ntl/ntl_mat_GF2E.cpython-314t-x86_64-linux-gnu.so +0 -0
  94. sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
  95. sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
  96. sage/libs/ntl/ntl_mat_ZZ.cpython-314t-x86_64-linux-gnu.so +0 -0
  97. sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
  98. sage/libs/ntl/ntl_mat_ZZ.pyx +1522 -0
  99. sage/libs/ntl/ntl_tools.pxd +3 -0
  100. sage/libs/ntl/ntlwrap.h +53 -0
  101. sage/libs/ntl/ntlwrap_impl.h +743 -0
  102. sage/libs/ntl/types.pxd +157 -0
  103. sage/libs/ntl/vec_GF2.pxd +26 -0
  104. sage/libs/ntl/vec_GF2E.pxd +2 -0
  105. sage/matrix/all__sagemath_ntl.py +1 -0
  106. sage/matrix/matrix_modn_dense_double.pxd +10 -0
  107. sage/matrix/matrix_modn_dense_float.pxd +9 -0
  108. sage/matrix/matrix_modn_dense_template.pxi +3475 -0
  109. sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
  110. sage/matrix/matrix_modn_sparse.pxd +8 -0
  111. sage/misc/all__sagemath_ntl.py +1 -0
  112. sage/rings/all__sagemath_ntl.py +7 -0
  113. sage/rings/bernmm.cpython-314t-x86_64-linux-gnu.so +0 -0
  114. sage/rings/bernmm.pyx +161 -0
  115. sage/rings/bernoulli_mod_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  116. sage/rings/bernoulli_mod_p.pyx +312 -0
  117. sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
  118. sage/rings/finite_rings/finite_field_ntl_gf2e.py +309 -0
  119. sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-314t-x86_64-linux-gnu.so +0 -0
  120. sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
  121. sage/rings/padics/all__sagemath_ntl.py +5 -0
  122. sage/rings/padics/padic_ZZ_pX_CA_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  123. sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
  124. sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2366 -0
  125. sage/rings/padics/padic_ZZ_pX_CR_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  126. sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
  127. sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3282 -0
  128. sage/rings/padics/padic_ZZ_pX_FM_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  129. sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
  130. sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1737 -0
  131. sage/rings/padics/padic_ZZ_pX_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  132. sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
  133. sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
  134. sage/rings/padics/padic_ext_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  135. sage/rings/padics/padic_ext_element.pxd +38 -0
  136. sage/rings/padics/padic_ext_element.pyx +513 -0
  137. sage/rings/padics/pow_computer_ext.cpython-314t-x86_64-linux-gnu.so +0 -0
  138. sage/rings/padics/pow_computer_ext.pxd +107 -0
  139. sage/rings/padics/pow_computer_ext.pyx +2402 -0
  140. sage/rings/polynomial/all__sagemath_ntl.py +1 -0
  141. sage/rings/polynomial/evaluation_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  142. sage/rings/polynomial/evaluation_ntl.pxd +7 -0
  143. sage/rings/polynomial/evaluation_ntl.pyx +70 -0
  144. sage/rings/polynomial/polynomial_gf2x.cpython-314t-x86_64-linux-gnu.so +0 -0
  145. sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
  146. sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
  147. sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  148. sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
  149. sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
  150. sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  151. sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
  152. sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2050 -0
  153. sage/rings/polynomial/polynomial_template.pxi +839 -0
  154. sage/rings/polynomial/polynomial_template_header.pxi +11 -0
  155. sage/rings/polynomial/polynomial_zz_pex.cpython-314t-x86_64-linux-gnu.so +0 -0
  156. sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
  157. sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
  158. sage/rings/real_mpfi.pxd +50 -0
  159. sage/schemes/all__sagemath_ntl.py +1 -0
  160. sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
  161. sage/schemes/hyperelliptic_curves/hypellfrob.cpython-314t-x86_64-linux-gnu.so +0 -0
  162. sage/schemes/hyperelliptic_curves/hypellfrob.pyx +253 -0
@@ -0,0 +1,1522 @@
1
+ # sage_setup: distribution = sagemath-ntl
2
+ # distutils: libraries = NTL_LIBRARIES gmp M_LIBRARIES
3
+ # distutils: extra_compile_args = NTL_CFLAGS
4
+ # distutils: include_dirs = NTL_INCDIR
5
+ # distutils: library_dirs = NTL_LIBDIR
6
+ # distutils: extra_link_args = NTL_LIBEXTRA
7
+ # distutils: language = c++
8
+ # sage.doctest: needs sage.libs.pari
9
+
10
+ #*****************************************************************************
11
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
12
+ #
13
+ # Distributed under the terms of the GNU General Public License (GPL)
14
+ #
15
+ # This code is distributed in the hope that it will be useful,
16
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
+ # General Public License for more details.
19
+ #
20
+ # The full text of the GPL is available at:
21
+ #
22
+ # http://www.gnu.org/licenses/
23
+ #*****************************************************************************
24
+
25
+ from cysignals.signals cimport sig_on, sig_off
26
+ from sage.ext.cplusplus cimport ccrepr
27
+
28
+ include 'misc.pxi'
29
+ include 'decl.pxi'
30
+
31
+ from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
32
+ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
33
+ from cpython.object cimport PyObject_RichCompare
34
+
35
+ from sage.libs.ntl.ntl_ZZ import unpickle_class_args
36
+
37
+ cdef inline ntl_ZZ make_ZZ(ZZ_c* x):
38
+ cdef ntl_ZZ y
39
+ y = ntl_ZZ()
40
+ y.x = x[0]
41
+ del x
42
+ return y
43
+
44
+ # You must do sig_on() before calling this function
45
+ cdef inline ntl_ZZ make_ZZ_sig_off(ZZ_c* x):
46
+ cdef ntl_ZZ y = make_ZZ(x)
47
+ sig_off()
48
+ return y
49
+
50
+ cdef inline ntl_mat_ZZ make_mat_ZZ(mat_ZZ_c* x):
51
+ cdef ntl_mat_ZZ y
52
+ y = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
53
+ y.x = x[0]
54
+ del x
55
+ y.__nrows = y.x.NumRows()
56
+ y.__ncols = y.x.NumCols()
57
+ return y
58
+
59
+ # You must do sig_on() before calling this function
60
+ cdef inline ntl_mat_ZZ make_mat_ZZ_sig_off(mat_ZZ_c* x):
61
+ cdef ntl_mat_ZZ y = make_mat_ZZ(x)
62
+ sig_off()
63
+ return y
64
+
65
+
66
+ ##############################################################################
67
+ #
68
+ # ntl_mat_ZZ: Matrices over the integers via NTL
69
+ #
70
+ ##############################################################################
71
+
72
+ cdef class ntl_mat_ZZ():
73
+ # see ntl_mat_ZZ.pxd for data members
74
+ r"""
75
+ The \class{mat_ZZ} class implements arithmetic with matrices over `\Z`.
76
+ """
77
+ def __init__(self, nrows=0, ncols=0, v=None):
78
+ r"""
79
+ The \class{mat_ZZ} class implements arithmetic with matrices over `\Z`.
80
+
81
+ EXAMPLES::
82
+
83
+ sage: M = ntl.mat_ZZ(3,3) ; M
84
+ [
85
+ [0 0 0]
86
+ [0 0 0]
87
+ [0 0 0]
88
+ ]
89
+ sage: ntl.mat_ZZ(3,3,[1..9])
90
+ [
91
+ [1 2 3]
92
+ [4 5 6]
93
+ [7 8 9]
94
+ ]
95
+ """
96
+ cdef unsigned long i, j
97
+ cdef ntl_ZZ tmp
98
+ if nrows == 0 and ncols == 0:
99
+ return
100
+ nrows = int(nrows)
101
+ ncols = int(ncols)
102
+ self.x.SetDims(nrows, ncols)
103
+ self.__nrows = nrows
104
+ self.__ncols = ncols
105
+ if v is not None:
106
+ for i from 0 <= i < nrows:
107
+ for j from 0 <= j < ncols:
108
+ tmp = ntl_ZZ(v[i*ncols+j])
109
+ mat_ZZ_setitem(&self.x, i, j, &tmp.x)
110
+
111
+ def __reduce__(self):
112
+ """
113
+ EXAMPLES::
114
+
115
+ sage: m = ntl.mat_ZZ(3, 2, range(6)); m
116
+ [
117
+ [0 1]
118
+ [2 3]
119
+ [4 5]
120
+ ]
121
+ sage: loads(dumps(m))
122
+ [
123
+ [0 1]
124
+ [2 3]
125
+ [4 5]
126
+ ]
127
+ sage: loads(dumps(m)) == m
128
+ True
129
+ """
130
+ return unpickle_class_args, (ntl_mat_ZZ, (self.__nrows, self.__ncols, self.list()))
131
+
132
+ def __repr__(self):
133
+ """
134
+ Return the string representation of ``self``.
135
+
136
+ EXAMPLES::
137
+
138
+ sage: M = ntl.mat_ZZ(2,3,[5..10]) ; M.__repr__()
139
+ '[\n[5 6 7]\n[8 9 10]\n]'
140
+ """
141
+ return ccrepr(self.x).replace('[[','[\n[',1)
142
+
143
+ def __mul__(ntl_mat_ZZ self, other):
144
+ """
145
+ Multiply two matrices.
146
+
147
+ EXAMPLES::
148
+
149
+ sage: M = ntl.mat_ZZ(2,2,[8..11]) ; N = ntl.mat_ZZ(2,2,[-1..2])
150
+ sage: M*N
151
+ [
152
+ [1 18]
153
+ [1 22]
154
+ ]
155
+ """
156
+ cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
157
+ if not isinstance(self, ntl_mat_ZZ):
158
+ self = ntl_mat_ZZ(self)
159
+ if not isinstance(other, ntl_mat_ZZ):
160
+ other = ntl_mat_ZZ(other)
161
+ sig_on()
162
+ mat_ZZ_mul(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
163
+ sig_off()
164
+ return r
165
+
166
+ def __sub__(ntl_mat_ZZ self, other):
167
+ """
168
+ Return ``self - other``.
169
+
170
+ EXAMPLES::
171
+
172
+ sage: M = ntl.mat_ZZ(2,2,[8..11]) ; N = ntl.mat_ZZ(2,2,[-1..2])
173
+ sage: M-N
174
+ [
175
+ [9 9]
176
+ [9 9]
177
+ ]
178
+ """
179
+ cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
180
+ if not isinstance(self, ntl_mat_ZZ):
181
+ self = ntl_mat_ZZ(self)
182
+ if not isinstance(other, ntl_mat_ZZ):
183
+ other = ntl_mat_ZZ(other)
184
+ sig_on()
185
+ mat_ZZ_sub(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
186
+ sig_off()
187
+ return r
188
+
189
+ def __add__(ntl_mat_ZZ self, other):
190
+ """
191
+ Return ``self + other``.
192
+
193
+ EXAMPLES::
194
+
195
+ sage: M = ntl.mat_ZZ(2,2,[8..11]) ; N = ntl.mat_ZZ(2,2,[-1..2])
196
+ sage: M+N
197
+ [
198
+ [7 9]
199
+ [11 13]
200
+ ]
201
+ """
202
+ cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
203
+ if not isinstance(self, ntl_mat_ZZ):
204
+ self = ntl_mat_ZZ(self)
205
+ if not isinstance(other, ntl_mat_ZZ):
206
+ other = ntl_mat_ZZ(other)
207
+ sig_on()
208
+ mat_ZZ_add(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
209
+ sig_off()
210
+ return r
211
+
212
+ def __richcmp__(ntl_mat_ZZ self, other, int op):
213
+ """
214
+ Compare ``self`` to ``other``.
215
+
216
+ EXAMPLES::
217
+
218
+ sage: M = ntl.mat_ZZ(2,2,[3..6])
219
+ sage: N = M^2
220
+ sage: M == M
221
+ True
222
+ sage: M == N
223
+ False
224
+ sage: M == 0
225
+ False
226
+ sage: M < ntl.mat_ZZ(2,2,[4,4,4,4])
227
+ True
228
+ sage: M != ntl.mat_ZZ(1,1,[3])
229
+ True
230
+ sage: M != 0
231
+ True
232
+ """
233
+ try:
234
+ <ntl_mat_ZZ?>other
235
+ except TypeError:
236
+ return NotImplemented
237
+ return PyObject_RichCompare(self.list(), other.list(), op)
238
+
239
+ def __pow__(ntl_mat_ZZ self, long e, ignored):
240
+ """
241
+ Return ``self`` to the e power.
242
+
243
+ EXAMPLES::
244
+
245
+ sage: M = ntl.mat_ZZ(2,2,[8..11])
246
+ sage: M**4
247
+ [
248
+ [56206 62415]
249
+ [69350 77011]
250
+ ]
251
+ sage: M**0
252
+ [
253
+ [1 0]
254
+ [0 1]
255
+ ]
256
+ sage: M**(-1)
257
+ Traceback (most recent call last):
258
+ ...
259
+ ValueError: cannot take negative powers of matrices.
260
+ """
261
+ if self.__nrows != self.__ncols:
262
+ raise TypeError("cannot take powers of non-square matrices.")
263
+ if e < 0:
264
+ raise ValueError("cannot take negative powers of matrices.")
265
+ cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
266
+ sig_on()
267
+ mat_ZZ_power(r.x, (<ntl_mat_ZZ>self).x, e)
268
+ sig_off()
269
+ return r
270
+
271
+ def nrows(self):
272
+ """
273
+ Return the number of rows in ``self``.
274
+
275
+ EXAMPLES::
276
+
277
+ sage: M = ntl.mat_ZZ(5,5,range(25))
278
+ sage: M.nrows()
279
+ 5
280
+ """
281
+ return self.__nrows
282
+
283
+ def ncols(self):
284
+ """
285
+ Return the number of columns in ``self``.
286
+
287
+ EXAMPLES::
288
+
289
+ sage: M = ntl.mat_ZZ(5,8,range(40))
290
+ sage: M.ncols()
291
+ 8
292
+ """
293
+ return self.__ncols
294
+
295
+ def __setitem__(self, ij, x):
296
+ """
297
+ Given a tuple (i, j), return self[i,j].
298
+
299
+ EXAMPLES::
300
+
301
+ sage: M = ntl.mat_ZZ(2,9,[3..20])
302
+ sage: M[1,7] ## indirect doctest
303
+ 19
304
+ """
305
+ cdef ntl_ZZ y
306
+ cdef int i, j
307
+ if not isinstance(x, ntl_ZZ):
308
+ y = ntl_ZZ(x)
309
+ else:
310
+ y = x
311
+ if not isinstance(ij, tuple) or len(ij) != 2:
312
+ raise TypeError('ij must be a 2-tuple')
313
+ i, j = int(ij[0]),int(ij[1])
314
+ if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
315
+ raise IndexError("array index out of range")
316
+ sig_on()
317
+ mat_ZZ_setitem(&self.x, i, j, &y.x)
318
+ sig_off()
319
+
320
+ def __getitem__(self, ij):
321
+ """
322
+ EXAMPLES::
323
+
324
+ sage: m = ntl.mat_ZZ(3, 2, range(6))
325
+ sage: m[0,0] ## indirect doctest
326
+ 0
327
+ sage: m[2,1]
328
+ 5
329
+ sage: m[3,2] # oops, 0 based
330
+ Traceback (most recent call last):
331
+ ...
332
+ IndexError: array index out of range
333
+ """
334
+ cdef int i, j
335
+ if not isinstance(ij, tuple) or len(ij) != 2:
336
+ raise TypeError('ij must be a 2-tuple')
337
+ i, j = ij
338
+ if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
339
+ raise IndexError("array index out of range")
340
+ sig_on()
341
+ return make_ZZ_sig_off(mat_ZZ_getitem(&self.x, i+1, j+1))
342
+
343
+ def list(self):
344
+ """
345
+ EXAMPLES::
346
+
347
+ sage: m = ntl.mat_ZZ(3, 4, range(12)); m
348
+ [
349
+ [0 1 2 3]
350
+ [4 5 6 7]
351
+ [8 9 10 11]
352
+ ]
353
+ sage: m.list()
354
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
355
+ """
356
+ cdef int i, j
357
+ sig_on()
358
+ L = [make_ZZ(mat_ZZ_getitem(&self.x, i+1, j+1))
359
+ for i from 0 <= i < self.__nrows
360
+ for j from 0 <= j < self.__ncols]
361
+ sig_off()
362
+ return L
363
+
364
+ def determinant(self, deterministic=True):
365
+ """
366
+ Return the determinant of ``self``.
367
+
368
+ EXAMPLES::
369
+
370
+ sage: ntl.mat_ZZ(8,8,[3..66]).determinant()
371
+ 0
372
+ sage: ntl.mat_ZZ(2,5,range(10)).determinant()
373
+ Traceback (most recent call last):
374
+ ...
375
+ TypeError: cannot take determinant of non-square matrix.
376
+ sage: ntl.mat_ZZ(4,4,[next_prime(2**i) for i in range(16)]).determinant()
377
+ -10248
378
+ sage: ntl.mat_ZZ(4,4,[ ZZ.random_element() for _ in range(16) ]).determinant() # random
379
+ 678
380
+ """
381
+ if self.__nrows != self.__ncols:
382
+ raise TypeError("cannot take determinant of non-square matrix.")
383
+ sig_on()
384
+ return make_ZZ_sig_off(mat_ZZ_determinant(&self.x, deterministic))
385
+
386
+ def HNF(self, D=None):
387
+ r"""
388
+ The input matrix A=self is an n x m matrix of rank m (so n >=
389
+ m), and D is a multiple of the determinant of the lattice L
390
+ spanned by the rows of A. The output W is the Hermite Normal
391
+ Form of A; that is, W is the unique m x m matrix whose rows
392
+ span L, such that
393
+
394
+ - W is lower triangular,
395
+ - the diagonal entries are positive,
396
+ - any entry below the diagonal is a nonnegative number
397
+ strictly less than the diagonal entry in its column.
398
+
399
+ This is implemented using the algorithm of [P. Domich,
400
+ R. Kannan and L. Trotter, Math. Oper. Research 12:50-59,
401
+ 1987].
402
+
403
+ TIMINGS:
404
+
405
+ NTL is not very good compared to MAGMA, unfortunately::
406
+
407
+ sage: a = MatrixSpace(ZZ,200).random_element(x=-2, y=2) # -2 to 2
408
+ sage: A = ntl.mat_ZZ(200,200)
409
+ sage: for i in range(a.nrows()):
410
+ ....: for j in range(a.ncols()):
411
+ ....: A[i,j] = a[i,j]
412
+ sage: t = cputime(); d = A.determinant()
413
+ sage: cputime(t) # random
414
+ 0.33201999999999998
415
+ sage: t = cputime(); B = A.HNF(d) # long time (5s on sage.math, 2011)
416
+ sage: cputime(t) # random
417
+ 6.4924050000000006
418
+
419
+ In comparison, MAGMA does this much more quickly:
420
+ \begin{verbatim}
421
+ > A := MatrixAlgebra(IntegerRing(),200)![Random(-2,2) : i in [1..200^2]];
422
+ > time d := Determinant(A);
423
+ Time: 0.140
424
+ > time H := HermiteForm(A);
425
+ Time: 0.290
426
+ \end{verbatim}
427
+
428
+ Also, PARI is also faster than NTL if one uses the flag 1 to
429
+ the mathnf routine. The above takes 16 seconds in PARI.
430
+
431
+ TESTS::
432
+
433
+ sage: ntl.mat_ZZ(2,2,[1..4]).HNF()
434
+ [
435
+ [1 0]
436
+ [0 2]
437
+ ]
438
+ """
439
+ cdef ntl_ZZ _D
440
+ if D is None:
441
+ _D = self.determinant()
442
+ else:
443
+ _D = ntl_ZZ(D)
444
+ sig_on()
445
+ return make_mat_ZZ_sig_off(mat_ZZ_HNF(&self.x, &_D.x))
446
+
447
+ def charpoly(self):
448
+ """
449
+ Find the characteristic polynomial of self, and return it
450
+ as an NTL ZZX.
451
+
452
+ EXAMPLES::
453
+
454
+ sage: M = ntl.mat_ZZ(2,2,[1,2,3,4])
455
+ sage: M.charpoly()
456
+ [-2 -5 1]
457
+ sage: type(_)
458
+ <class 'sage.libs.ntl.ntl_ZZX.ntl_ZZX'>
459
+ sage: M.determinant()
460
+ -2
461
+ """
462
+ cdef ntl_ZZX r = ntl_ZZX()
463
+ sig_on()
464
+ mat_ZZ_CharPoly(r.x, self.x)
465
+ sig_off()
466
+ return r
467
+
468
+ def BKZ_FP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
469
+ r"""
470
+ All BKZ methods are equivalent to the LLL routines,
471
+ except that Block Korkin-Zolotarev reduction is applied. We
472
+ describe here only the differences in the calling syntax.
473
+
474
+ * The optional parameter "BlockSize" specifies the size of the
475
+ blocks in the reduction. High values yield shorter vectors,
476
+ but the running time increases exponentially with BlockSize.
477
+ BlockSize should be between 2 and the number of rows of B.
478
+
479
+ * The optional parameter "prune" can be set to any positive
480
+ number to invoke the Volume Heuristic from [Schnorr and
481
+ Horner, Eurocrypt '95]. This can significantly reduce the
482
+ running time, and hence allow much bigger block size, but the
483
+ quality of the reduction is of course not as good in general.
484
+ Higher values of prune mean better quality, and slower running
485
+ time. When prune == 0, pruning is disabled. Recommended
486
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
487
+
488
+ * The QP1 variant uses quad_float precision to compute
489
+ Gram-Schmidt, but uses double precision in the search phase
490
+ of the block reduction algorithm. This seems adequate for
491
+ most purposes, and is faster than QP, which uses quad_float
492
+ precision uniformly throughout.
493
+
494
+ INPUT:
495
+
496
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
497
+ - ``delta`` -- reduction parameter (default: 0.99)
498
+ - ``BlockSize`` -- see above (default: 10)
499
+ - ``prune`` -- see above (default: 0)
500
+ - ``verbose`` -- print verbose output (default: ``False``)
501
+
502
+ EXAMPLES::
503
+
504
+ sage: A = Matrix(ZZ,5,5,range(25))
505
+ sage: a = A._ntl_()
506
+ sage: a.BKZ_FP(); a
507
+ 2
508
+ [
509
+ [0 0 0 0 0]
510
+ [0 0 0 0 0]
511
+ [0 0 0 0 0]
512
+ [0 1 2 3 4]
513
+ [5 3 1 -1 -3]
514
+ ]
515
+
516
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
517
+ sage: r = a.BKZ_FP(U=U); U
518
+ [
519
+ [0 1 0 0 0]
520
+ [1 0 0 0 0]
521
+ [0 0 1 0 0]
522
+ [0 0 0 1 0]
523
+ [0 0 0 0 1]
524
+ ]
525
+ """
526
+ if U is None:
527
+ sig_on()
528
+ rank = mat_ZZ_BKZ_FP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
529
+ sig_off()
530
+ return rank
531
+ elif isinstance(U, ntl_mat_ZZ):
532
+ sig_on()
533
+ rank = mat_ZZ_BKZ_FP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
534
+ sig_off()
535
+ return rank
536
+ else:
537
+ raise TypeError("parameter U has wrong type.")
538
+
539
+ def BKZ_QP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
540
+ r"""
541
+ All BKZ methods are equivalent to the LLL routines,
542
+ except that Block Korkin-Zolotarev reduction is applied. We
543
+ describe here only the differences in the calling syntax.
544
+
545
+ * The optional parameter "BlockSize" specifies the size of the
546
+ blocks in the reduction. High values yield shorter vectors,
547
+ but the running time increases exponentially with BlockSize.
548
+ BlockSize should be between 2 and the number of rows of B.
549
+
550
+ * The optional parameter "prune" can be set to any positive
551
+ number to invoke the Volume Heuristic from [Schnorr and
552
+ Horner, Eurocrypt '95]. This can significantly reduce the
553
+ running time, and hence allow much bigger block size, but the
554
+ quality of the reduction is of course not as good in general.
555
+ Higher values of prune mean better quality, and slower running
556
+ time. When prune == 0, pruning is disabled. Recommended
557
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
558
+
559
+ * The QP1 variant uses quad_float precision to compute
560
+ Gram-Schmidt, but uses double precision in the search phase
561
+ of the block reduction algorithm. This seems adequate for
562
+ most purposes, and is faster than QP, which uses quad_float
563
+ precision uniformly throughout.
564
+
565
+ INPUT:
566
+
567
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
568
+ - ``delta`` -- reduction parameter (default: 0.99)
569
+ - ``BlockSize`` -- see above (default: 10)
570
+ - ``prune`` -- see above (default: 0)
571
+ - ``verbose`` -- print verbose output (default: ``False``)
572
+
573
+ EXAMPLES::
574
+
575
+ sage: A = Matrix(ZZ,5,5,range(25))
576
+ sage: a = A._ntl_()
577
+ sage: a.BKZ_QP(); a
578
+ 2
579
+ [
580
+ [0 0 0 0 0]
581
+ [0 0 0 0 0]
582
+ [0 0 0 0 0]
583
+ [0 1 2 3 4]
584
+ [5 3 1 -1 -3]
585
+ ]
586
+
587
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
588
+ sage: r = a.BKZ_QP(U=U); U
589
+ [
590
+ [0 1 0 0 0]
591
+ [1 0 0 0 0]
592
+ [0 0 1 0 0]
593
+ [0 0 0 1 0]
594
+ [0 0 0 0 1]
595
+ ]
596
+ """
597
+ if U is None:
598
+ sig_on()
599
+ rank = mat_ZZ_BKZ_QP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
600
+ sig_off()
601
+ return rank
602
+ elif isinstance(U, ntl_mat_ZZ):
603
+ sig_on()
604
+ rank = mat_ZZ_BKZ_QP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
605
+ sig_off()
606
+ return rank
607
+ else:
608
+ raise TypeError("parameter U has wrong type.")
609
+
610
+ def BKZ_QP1(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
611
+ r"""
612
+ All BKZ methods are equivalent to the LLL routines,
613
+ except that Block Korkin-Zolotarev reduction is applied. We
614
+ describe here only the differences in the calling syntax.
615
+
616
+ * The optional parameter "BlockSize" specifies the size of the
617
+ blocks in the reduction. High values yield shorter vectors,
618
+ but the running time increases exponentially with BlockSize.
619
+ BlockSize should be between 2 and the number of rows of B.
620
+
621
+ * The optional parameter "prune" can be set to any positive
622
+ number to invoke the Volume Heuristic from [Schnorr and
623
+ Horner, Eurocrypt '95]. This can significantly reduce the
624
+ running time, and hence allow much bigger block size, but the
625
+ quality of the reduction is of course not as good in general.
626
+ Higher values of prune mean better quality, and slower running
627
+ time. When prune == 0, pruning is disabled. Recommended
628
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
629
+
630
+ * The QP1 variant uses quad_float precision to compute
631
+ Gram-Schmidt, but uses double precision in the search phase
632
+ of the block reduction algorithm. This seems adequate for
633
+ most purposes, and is faster than QP, which uses quad_float
634
+ precision uniformly throughout.
635
+
636
+ INPUT:
637
+
638
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
639
+ - ``delta`` -- reduction parameter (default: 0.99)
640
+ - ``BlockSize`` -- see above (default: 10)
641
+ - ``prune`` -- see above (default: 0)
642
+ - ``verbose`` -- print verbose output (default: ``False``)
643
+
644
+ EXAMPLES::
645
+
646
+ sage: A = Matrix(ZZ,5,5,range(25))
647
+ sage: a = A._ntl_()
648
+ sage: a.BKZ_QP1(); a
649
+ 2
650
+ [
651
+ [0 0 0 0 0]
652
+ [0 0 0 0 0]
653
+ [0 0 0 0 0]
654
+ [0 1 2 3 4]
655
+ [5 3 1 -1 -3]
656
+ ]
657
+
658
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
659
+ sage: r = a.BKZ_QP1(U=U); U
660
+ [
661
+ [0 1 0 0 0]
662
+ [1 0 0 0 0]
663
+ [0 0 1 0 0]
664
+ [0 0 0 1 0]
665
+ [0 0 0 0 1]
666
+ ]
667
+ """
668
+ if U is None:
669
+ sig_on()
670
+ rank = mat_ZZ_BKZ_QP1(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
671
+ sig_off()
672
+ return rank
673
+ elif isinstance(U, ntl_mat_ZZ):
674
+ sig_on()
675
+ rank = mat_ZZ_BKZ_QP1_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
676
+ sig_off()
677
+ return rank
678
+ else:
679
+ raise TypeError("parameter U has wrong type.")
680
+
681
+ def BKZ_XD(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
682
+ r"""
683
+ All BKZ methods are equivalent to the LLL routines,
684
+ except that Block Korkin-Zolotarev reduction is applied. We
685
+ describe here only the differences in the calling syntax.
686
+
687
+ * The optional parameter "BlockSize" specifies the size of the
688
+ blocks in the reduction. High values yield shorter vectors,
689
+ but the running time increases exponentially with BlockSize.
690
+ BlockSize should be between 2 and the number of rows of B.
691
+
692
+ * The optional parameter "prune" can be set to any positive
693
+ number to invoke the Volume Heuristic from [Schnorr and
694
+ Horner, Eurocrypt '95]. This can significantly reduce the
695
+ running time, and hence allow much bigger block size, but the
696
+ quality of the reduction is of course not as good in general.
697
+ Higher values of prune mean better quality, and slower running
698
+ time. When prune == 0, pruning is disabled. Recommended
699
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
700
+
701
+ * The QP1 variant uses quad_float precision to compute
702
+ Gram-Schmidt, but uses double precision in the search phase
703
+ of the block reduction algorithm. This seems adequate for
704
+ most purposes, and is faster than QP, which uses quad_float
705
+ precision uniformly throughout.
706
+
707
+ INPUT:
708
+
709
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
710
+ - ``delta`` -- reduction parameter (default: 0.99)
711
+ - ``BlockSize`` -- see above (default: 10)
712
+ - ``prune`` -- see above (default: 0)
713
+ - ``verbose`` -- print verbose output (default: ``False``)
714
+
715
+ EXAMPLES::
716
+
717
+ sage: A = Matrix(ZZ,5,5,range(25))
718
+ sage: a = A._ntl_()
719
+ sage: a.BKZ_XD(); a
720
+ 2
721
+ [
722
+ [0 0 0 0 0]
723
+ [0 0 0 0 0]
724
+ [0 0 0 0 0]
725
+ [0 1 2 3 4]
726
+ [5 3 1 -1 -3]
727
+ ]
728
+
729
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
730
+ sage: r = a.BKZ_XD(U=U); U
731
+ [
732
+ [0 1 0 0 0]
733
+ [1 0 0 0 0]
734
+ [0 0 1 0 0]
735
+ [0 0 0 1 0]
736
+ [0 0 0 0 1]
737
+ ]
738
+ """
739
+ if U is None:
740
+ sig_on()
741
+ rank = mat_ZZ_BKZ_XD(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
742
+ sig_off()
743
+ return rank
744
+ elif isinstance(U, ntl_mat_ZZ):
745
+ sig_on()
746
+ rank = mat_ZZ_BKZ_XD_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
747
+ sig_off()
748
+ return rank
749
+ else:
750
+ raise TypeError("parameter U has wrong type.")
751
+
752
+ def BKZ_RR(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
753
+ r"""
754
+ All BKZ methods are equivalent to the LLL routines,
755
+ except that Block Korkin-Zolotarev reduction is applied. We
756
+ describe here only the differences in the calling syntax.
757
+
758
+ * The optional parameter "BlockSize" specifies the size of the
759
+ blocks in the reduction. High values yield shorter vectors,
760
+ but the running time increases exponentially with BlockSize.
761
+ BlockSize should be between 2 and the number of rows of B.
762
+
763
+ * The optional parameter "prune" can be set to any positive
764
+ number to invoke the Volume Heuristic from [Schnorr and
765
+ Horner, Eurocrypt '95]. This can significantly reduce the
766
+ running time, and hence allow much bigger block size, but the
767
+ quality of the reduction is of course not as good in general.
768
+ Higher values of prune mean better quality, and slower running
769
+ time. When prune == 0, pruning is disabled. Recommended
770
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
771
+
772
+ * The QP1 variant uses quad_float precision to compute
773
+ Gram-Schmidt, but uses double precision in the search phase
774
+ of the block reduction algorithm. This seems adequate for
775
+ most purposes, and is faster than QP, which uses quad_float
776
+ precision uniformly throughout.
777
+
778
+ INPUT:
779
+
780
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
781
+ - ``delta`` -- reduction parameter (default: 0.99)
782
+ - ``BlockSize`` -- see above (default: 10)
783
+ - ``prune`` -- see above (default: 0)
784
+ - ``verbose`` -- print verbose output (default: ``False``)
785
+
786
+ EXAMPLES::
787
+
788
+ sage: A = Matrix(ZZ,5,5,range(25))
789
+ sage: a = A._ntl_()
790
+ sage: a.BKZ_RR(); a
791
+ 2
792
+ [
793
+ [0 0 0 0 0]
794
+ [0 0 0 0 0]
795
+ [0 0 0 0 0]
796
+ [0 1 2 3 4]
797
+ [5 3 1 -1 -3]
798
+ ]
799
+
800
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
801
+ sage: r = a.BKZ_RR(U=U); U
802
+ [
803
+ [0 1 0 0 0]
804
+ [1 0 0 0 0]
805
+ [0 0 1 0 0]
806
+ [0 0 0 1 0]
807
+ [0 0 0 0 1]
808
+ ]
809
+ """
810
+ if U is None:
811
+ sig_on()
812
+ rank = mat_ZZ_BKZ_RR(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
813
+ sig_off()
814
+ return rank
815
+ elif isinstance(U, ntl_mat_ZZ):
816
+ sig_on()
817
+ rank = mat_ZZ_BKZ_RR_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
818
+ sig_off()
819
+ return rank
820
+ else:
821
+ raise TypeError("parameter U has wrong type.")
822
+
823
+ def G_BKZ_FP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
824
+ r"""
825
+ All BKZ methods are equivalent to the LLL routines,
826
+ except that Block Korkin-Zolotarev reduction is applied. We
827
+ describe here only the differences in the calling syntax.
828
+
829
+ * The optional parameter "BlockSize" specifies the size of the
830
+ blocks in the reduction. High values yield shorter vectors,
831
+ but the running time increases exponentially with BlockSize.
832
+ BlockSize should be between 2 and the number of rows of B.
833
+
834
+ * The optional parameter "prune" can be set to any positive
835
+ number to invoke the Volume Heuristic from [Schnorr and
836
+ Horner, Eurocrypt '95]. This can significantly reduce the
837
+ running time, and hence allow much bigger block size, but the
838
+ quality of the reduction is of course not as good in general.
839
+ Higher values of prune mean better quality, and slower running
840
+ time. When prune == 0, pruning is disabled. Recommended
841
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
842
+
843
+ * The QP1 variant uses quad_float precision to compute
844
+ Gram-Schmidt, but uses double precision in the search phase
845
+ of the block reduction algorithm. This seems adequate for
846
+ most purposes, and is faster than QP, which uses quad_float
847
+ precision uniformly throughout.
848
+
849
+ INPUT:
850
+
851
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
852
+ - ``delta`` -- reduction parameter (default: 0.99)
853
+ - ``BlockSize`` -- see above (default: 10)
854
+ - ``prune`` -- see above (default: 0)
855
+ - ``verbose`` -- print verbose output (default: ``False``)
856
+
857
+ EXAMPLES::
858
+
859
+ sage: A = Matrix(ZZ,5,5,range(25))
860
+ sage: a = A._ntl_()
861
+ sage: a.G_BKZ_FP(); a
862
+ 2
863
+ [
864
+ [0 0 0 0 0]
865
+ [0 0 0 0 0]
866
+ [0 0 0 0 0]
867
+ [0 1 2 3 4]
868
+ [5 3 1 -1 -3]
869
+ ]
870
+
871
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
872
+ sage: r = a.G_BKZ_FP(U=U); U
873
+ [
874
+ [0 1 0 0 0]
875
+ [1 0 0 0 0]
876
+ [0 0 1 0 0]
877
+ [0 0 0 1 0]
878
+ [0 0 0 0 1]
879
+ ]
880
+ """
881
+ if U is None:
882
+ sig_on()
883
+ rank = mat_ZZ_G_BKZ_FP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
884
+ sig_off()
885
+ return rank
886
+ elif isinstance(U, ntl_mat_ZZ):
887
+ sig_on()
888
+ rank = mat_ZZ_G_BKZ_FP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
889
+ sig_off()
890
+ return rank
891
+ else:
892
+ raise TypeError("parameter U has wrong type.")
893
+
894
+ def G_BKZ_QP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
895
+ r"""
896
+ All BKZ methods are equivalent to the LLL routines,
897
+ except that Block Korkin-Zolotarev reduction is applied. We
898
+ describe here only the differences in the calling syntax.
899
+
900
+ * The optional parameter "BlockSize" specifies the size of the
901
+ blocks in the reduction. High values yield shorter vectors,
902
+ but the running time increases exponentially with BlockSize.
903
+ BlockSize should be between 2 and the number of rows of B.
904
+
905
+ * The optional parameter "prune" can be set to any positive
906
+ number to invoke the Volume Heuristic from [Schnorr and
907
+ Horner, Eurocrypt '95]. This can significantly reduce the
908
+ running time, and hence allow much bigger block size, but the
909
+ quality of the reduction is of course not as good in general.
910
+ Higher values of prune mean better quality, and slower running
911
+ time. When prune == 0, pruning is disabled. Recommended
912
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
913
+
914
+ * The QP1 variant uses quad_float precision to compute
915
+ Gram-Schmidt, but uses double precision in the search phase
916
+ of the block reduction algorithm. This seems adequate for
917
+ most purposes, and is faster than QP, which uses quad_float
918
+ precision uniformly throughout.
919
+
920
+ INPUT:
921
+
922
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
923
+ - ``delta`` -- reduction parameter (default: 0.99)
924
+ - ``BlockSize`` -- see above (default: 10)
925
+ - ``prune`` -- see above (default: 0)
926
+ - ``verbose`` -- print verbose output (default: ``False``)
927
+
928
+ EXAMPLES::
929
+
930
+ sage: A = Matrix(ZZ,5,5,range(25))
931
+ sage: a = A._ntl_()
932
+ sage: a.G_BKZ_QP(); a
933
+ 2
934
+ [
935
+ [0 0 0 0 0]
936
+ [0 0 0 0 0]
937
+ [0 0 0 0 0]
938
+ [0 1 2 3 4]
939
+ [5 3 1 -1 -3]
940
+ ]
941
+
942
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
943
+ sage: r = a.G_BKZ_QP(U=U); U
944
+ [
945
+ [0 1 0 0 0]
946
+ [1 0 0 0 0]
947
+ [0 0 1 0 0]
948
+ [0 0 0 1 0]
949
+ [0 0 0 0 1]
950
+ ]
951
+ """
952
+ if U is None:
953
+ sig_on()
954
+ rank = mat_ZZ_G_BKZ_QP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
955
+ sig_off()
956
+ return rank
957
+ elif isinstance(U, ntl_mat_ZZ):
958
+ sig_on()
959
+ rank = mat_ZZ_G_BKZ_QP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
960
+ sig_off()
961
+ return rank
962
+ else:
963
+ raise TypeError("parameter U has wrong type.")
964
+
965
+ def G_BKZ_QP1(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
966
+ r"""
967
+ All BKZ methods are equivalent to the LLL routines,
968
+ except that Block Korkin-Zolotarev reduction is applied. We
969
+ describe here only the differences in the calling syntax.
970
+
971
+ * The optional parameter "BlockSize" specifies the size of the
972
+ blocks in the reduction. High values yield shorter vectors,
973
+ but the running time increases exponentially with BlockSize.
974
+ BlockSize should be between 2 and the number of rows of B.
975
+
976
+ * The optional parameter "prune" can be set to any positive
977
+ number to invoke the Volume Heuristic from [Schnorr and
978
+ Horner, Eurocrypt '95]. This can significantly reduce the
979
+ running time, and hence allow much bigger block size, but the
980
+ quality of the reduction is of course not as good in general.
981
+ Higher values of prune mean better quality, and slower running
982
+ time. When prune == 0, pruning is disabled. Recommended
983
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
984
+
985
+ * The QP1 variant uses quad_float precision to compute
986
+ Gram-Schmidt, but uses double precision in the search phase
987
+ of the block reduction algorithm. This seems adequate for
988
+ most purposes, and is faster than QP, which uses quad_float
989
+ precision uniformly throughout.
990
+
991
+ INPUT:
992
+
993
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
994
+ - ``delta`` -- reduction parameter (default: 0.99)
995
+ - ``BlockSize`` -- see above (default: 10)
996
+ - ``prune`` -- see above (default: 0)
997
+ - ``verbose`` -- print verbose output (default: ``False``)
998
+
999
+ EXAMPLES::
1000
+
1001
+ sage: A = Matrix(ZZ,5,5,range(25))
1002
+ sage: a = A._ntl_()
1003
+ sage: a.G_BKZ_QP1(); a
1004
+ 2
1005
+ [
1006
+ [0 0 0 0 0]
1007
+ [0 0 0 0 0]
1008
+ [0 0 0 0 0]
1009
+ [0 1 2 3 4]
1010
+ [5 3 1 -1 -3]
1011
+ ]
1012
+
1013
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
1014
+ sage: r = a.G_BKZ_QP1(U=U); U
1015
+ [
1016
+ [0 1 0 0 0]
1017
+ [1 0 0 0 0]
1018
+ [0 0 1 0 0]
1019
+ [0 0 0 1 0]
1020
+ [0 0 0 0 1]
1021
+ ]
1022
+ """
1023
+ if U is None:
1024
+ sig_on()
1025
+ rank = mat_ZZ_G_BKZ_QP1(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
1026
+ sig_off()
1027
+ return rank
1028
+ elif isinstance(U, ntl_mat_ZZ):
1029
+ sig_on()
1030
+ rank = mat_ZZ_G_BKZ_QP1_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
1031
+ sig_off()
1032
+ return rank
1033
+ else:
1034
+ raise TypeError("parameter U has wrong type.")
1035
+
1036
+ def G_BKZ_XD(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
1037
+ r"""
1038
+ All BKZ methods are equivalent to the LLL routines,
1039
+ except that Block Korkin-Zolotarev reduction is applied. We
1040
+ describe here only the differences in the calling syntax.
1041
+
1042
+ * The optional parameter "BlockSize" specifies the size of the
1043
+ blocks in the reduction. High values yield shorter vectors,
1044
+ but the running time increases exponentially with BlockSize.
1045
+ BlockSize should be between 2 and the number of rows of B.
1046
+
1047
+ * The optional parameter "prune" can be set to any positive
1048
+ number to invoke the Volume Heuristic from [Schnorr and
1049
+ Horner, Eurocrypt '95]. This can significantly reduce the
1050
+ running time, and hence allow much bigger block size, but the
1051
+ quality of the reduction is of course not as good in general.
1052
+ Higher values of prune mean better quality, and slower running
1053
+ time. When prune == 0, pruning is disabled. Recommended
1054
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
1055
+
1056
+ * The QP1 variant uses quad_float precision to compute
1057
+ Gram-Schmidt, but uses double precision in the search phase
1058
+ of the block reduction algorithm. This seems adequate for
1059
+ most purposes, and is faster than QP, which uses quad_float
1060
+ precision uniformly throughout.
1061
+
1062
+ INPUT:
1063
+
1064
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
1065
+ - ``delta`` -- reduction parameter (default: 0.99)
1066
+ - ``BlockSize`` -- see above (default: 10)
1067
+ - ``prune`` -- see above (default: 0)
1068
+ - ``verbose`` -- print verbose output (default: ``False``)
1069
+
1070
+ EXAMPLES::
1071
+
1072
+ sage: A = Matrix(ZZ,5,5,range(25))
1073
+ sage: a = A._ntl_()
1074
+ sage: a.G_BKZ_XD(); a
1075
+ 2
1076
+ [
1077
+ [0 0 0 0 0]
1078
+ [0 0 0 0 0]
1079
+ [0 0 0 0 0]
1080
+ [0 1 2 3 4]
1081
+ [5 3 1 -1 -3]
1082
+ ]
1083
+
1084
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
1085
+ sage: r = a.G_BKZ_XD(U=U); U
1086
+ [
1087
+ [0 1 0 0 0]
1088
+ [1 0 0 0 0]
1089
+ [0 0 1 0 0]
1090
+ [0 0 0 1 0]
1091
+ [0 0 0 0 1]
1092
+ ]
1093
+ """
1094
+ if U is None:
1095
+ sig_on()
1096
+ rank = mat_ZZ_G_BKZ_XD(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
1097
+ sig_off()
1098
+ return rank
1099
+ elif isinstance(U, ntl_mat_ZZ):
1100
+ sig_on()
1101
+ rank = mat_ZZ_G_BKZ_XD_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
1102
+ sig_off()
1103
+ return rank
1104
+ else:
1105
+ raise TypeError("parameter U has wrong type.")
1106
+
1107
+ def G_BKZ_RR(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
1108
+ r"""
1109
+ All BKZ methods are equivalent to the LLL routines,
1110
+ except that Block Korkin-Zolotarev reduction is applied. We
1111
+ describe here only the differences in the calling syntax.
1112
+
1113
+ * The optional parameter "BlockSize" specifies the size of the
1114
+ blocks in the reduction. High values yield shorter vectors,
1115
+ but the running time increases exponentially with BlockSize.
1116
+ BlockSize should be between 2 and the number of rows of B.
1117
+
1118
+ * The optional parameter "prune" can be set to any positive
1119
+ number to invoke the Volume Heuristic from [Schnorr and
1120
+ Horner, Eurocrypt '95]. This can significantly reduce the
1121
+ running time, and hence allow much bigger block size, but the
1122
+ quality of the reduction is of course not as good in general.
1123
+ Higher values of prune mean better quality, and slower running
1124
+ time. When prune == 0, pruning is disabled. Recommended
1125
+ usage: for BlockSize >= 30, set 10 <= prune <= 15.
1126
+
1127
+ * The QP1 variant uses quad_float precision to compute
1128
+ Gram-Schmidt, but uses double precision in the search phase
1129
+ of the block reduction algorithm. This seems adequate for
1130
+ most purposes, and is faster than QP, which uses quad_float
1131
+ precision uniformly throughout.
1132
+
1133
+ INPUT:
1134
+
1135
+ - ``U`` -- permutation matrix (see LLL, default: ``None``)
1136
+ - ``delta`` -- reduction parameter (default: 0.99)
1137
+ - ``BlockSize`` -- see above (default: 10)
1138
+ - ``prune`` -- see above (default: 0)
1139
+ - ``verbose`` -- print verbose output (default: ``False``)
1140
+
1141
+ EXAMPLES::
1142
+
1143
+ sage: A = Matrix(ZZ,5,5,range(25))
1144
+ sage: a = A._ntl_()
1145
+ sage: a.G_BKZ_RR(); a
1146
+ 2
1147
+ [
1148
+ [0 0 0 0 0]
1149
+ [0 0 0 0 0]
1150
+ [0 0 0 0 0]
1151
+ [0 1 2 3 4]
1152
+ [5 3 1 -1 -3]
1153
+ ]
1154
+
1155
+ sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
1156
+ sage: r = a.G_BKZ_RR(U=U); U
1157
+ [
1158
+ [0 1 0 0 0]
1159
+ [1 0 0 0 0]
1160
+ [0 0 1 0 0]
1161
+ [0 0 0 1 0]
1162
+ [0 0 0 0 1]
1163
+ ]
1164
+ """
1165
+ if U is None:
1166
+ sig_on()
1167
+ rank = mat_ZZ_G_BKZ_RR(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
1168
+ sig_off()
1169
+ return rank
1170
+ elif isinstance(U, ntl_mat_ZZ):
1171
+ sig_on()
1172
+ rank = mat_ZZ_G_BKZ_RR_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
1173
+ sig_off()
1174
+ return rank
1175
+ else:
1176
+ raise TypeError("parameter U has wrong type.")
1177
+
1178
+ def LLL(self, a=3, b=4, return_U=False, verbose=False):
1179
+ r"""
1180
+ Perform LLL reduction of ``self`` (puts \code{self} in an LLL form).
1181
+
1182
+ \code{self} is an `m x n` matrix, viewed as `m` rows of
1183
+ `n`-vectors. `m` may be less than, equal to, or greater than `n`,
1184
+ and the rows need not be linearly independent. ``self`` is
1185
+ transformed into an LLL-reduced basis, and the return value is
1186
+ the rank r of ``self`` so as det2 (see below). The first `m-r` rows
1187
+ of ``self`` are zero.
1188
+
1189
+ More specifically, elementary row transformations are
1190
+ performed on \code{self} so that the nonzero rows of
1191
+ new-\code{self} form an LLL-reduced basis for the lattice
1192
+ spanned by the rows of old-\code{self}. The default reduction
1193
+ parameter is `\delta=3/4`, which means that the squared length
1194
+ of the first nonzero basis vector is no more than `2^{r-1}`
1195
+ times that of the shortest vector in the lattice.
1196
+
1197
+ det2 is calculated as the \emph{square} of the determinant of
1198
+ the lattice---note that sqrt(det2) is in general an integer
1199
+ only when r = n.
1200
+
1201
+ If return_U is True, a value U is returned which is the
1202
+ transformation matrix, so that U is a unimodular m x m matrix
1203
+ with U * old-\code{self} = new-\code{self}. Note that the
1204
+ first m-r rows of U form a basis (as a lattice) for the kernel
1205
+ of old-B.
1206
+
1207
+ The parameters a and b allow an arbitrary reduction parameter
1208
+ `\delta=a/b`, where `1/4 < a/b \leq 1`, where a and b are positive
1209
+ integers. For a basis reduced with parameter delta, the
1210
+ squared length of the first nonzero basis vector is no more
1211
+ than `1/(delta-1/4)^{r-1}` times that of the shortest vector in
1212
+ the lattice.
1213
+
1214
+ The algorithm employed here is essentially the one in Cohen's
1215
+ book: [H. Cohen, A Course in Computational Algebraic Number
1216
+ Theory, Springer, 1993]
1217
+
1218
+ INPUT:
1219
+
1220
+ - ``a`` -- parameter a as described above (default: 3)
1221
+ - ``b`` -- parameter b as described above (default: 4)
1222
+ - ``return_U`` -- return U as described above
1223
+ - ``verbose`` -- if ``True`` NTL will produce some verbatim messages on
1224
+ what's going on internally (default: ``False``)
1225
+
1226
+ OUTPUT:
1227
+
1228
+ (rank,det2,[U]) where rank,det2, and U are as described
1229
+ above and U is an optional return value if return_U is ``True``.
1230
+
1231
+ EXAMPLES::
1232
+
1233
+ sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
1234
+ sage: M.LLL()
1235
+ (2, 54)
1236
+ sage: M
1237
+ [
1238
+ [0 0 0]
1239
+ [2 1 0]
1240
+ [-1 1 3]
1241
+ ]
1242
+ sage: M=ntl.mat_ZZ(4,4,[-6,9,-15,-18,4,-6,10,12,10,-16,18,35,-24,36,-46,-82]); M
1243
+ [
1244
+ [-6 9 -15 -18]
1245
+ [4 -6 10 12]
1246
+ [10 -16 18 35]
1247
+ [-24 36 -46 -82]
1248
+ ]
1249
+ sage: M.LLL()
1250
+ (3, 19140)
1251
+ sage: M
1252
+ [
1253
+ [0 0 0 0]
1254
+ [0 -2 0 0]
1255
+ [-2 1 -5 -6]
1256
+ [0 -1 -7 5]
1257
+ ]
1258
+
1259
+ WARNING: This method modifies \code{self}. So after applying
1260
+ this method your matrix will be a vector of vectors.
1261
+ """
1262
+ cdef ZZ_c *det2
1263
+ cdef ntl_mat_ZZ U
1264
+ if return_U:
1265
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1266
+ sig_on()
1267
+ rank = int(mat_ZZ_LLL_U(&det2, &self.x, &U.x, int(a), int(b), int(verbose)))
1268
+
1269
+ return rank, make_ZZ_sig_off(det2), U
1270
+ else:
1271
+ sig_on()
1272
+ rank = int(mat_ZZ_LLL(&det2,&self.x,int(a),int(b),int(verbose)))
1273
+ return rank, make_ZZ_sig_off(det2)
1274
+
1275
+ def LLL_FP(self, delta=0.75, return_U=False, verbose=False):
1276
+ r"""
1277
+ Perform approximate LLL reduction of \code{self} (puts
1278
+ \code{self} in an LLL form) subject to the following
1279
+ conditions:
1280
+
1281
+ The precision is double.
1282
+
1283
+ The return value is the rank of B.
1284
+
1285
+ Classical Gram-Schmidt Orthogonalization is used:
1286
+
1287
+ This choice uses classical methods for computing the
1288
+ Gram-Schmidt orthogonalization. It is fast but prone to
1289
+ stability problems. This strategy was first proposed by
1290
+ Schnorr and Euchner [C. P. Schnorr and M. Euchner,
1291
+ Proc. Fundamentals of Computation Theory, LNCS 529, pp. 68-85,
1292
+ 1991]. The version implemented here is substantially
1293
+ different, improving both stability and performance.
1294
+
1295
+ If return_U is True, then also U is returned which is
1296
+ the transition matrix: `U * self_{old} = self_{new}`
1297
+
1298
+ The optional argument 'delta' is the reduction parameter, and
1299
+ may be set so that 0.50 <= delta < 1. Setting it close to 1
1300
+ yields shorter vectors, and also improves the stability, but
1301
+ increases the running time. Recommended value: delta =
1302
+ 0.99.
1303
+
1304
+ The optional parameter 'verbose' can be set to see all kinds
1305
+ of fun things printed while the routine is executing. A
1306
+ status report is also printed every once in a while.
1307
+
1308
+ INPUT:
1309
+
1310
+ - ``delta`` -- as described above (0.5 <= delta < 1.0) (default: 0.75)
1311
+ - ``return_U`` -- return U as described above
1312
+ - ``verbose`` -- if ``True`` NTL will produce some verbatim messages on
1313
+ what's going on internally (default: ``False``)
1314
+
1315
+ OUTPUT:
1316
+
1317
+ (rank,[U]) where rank and U are as described above and U
1318
+ is an optional return value if ``return_U`` is ``True``.
1319
+
1320
+ EXAMPLES::
1321
+
1322
+ sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
1323
+ sage: M.LLL_FP()
1324
+ 2
1325
+ sage: M
1326
+ [
1327
+ [0 0 0]
1328
+ [2 1 0]
1329
+ [-1 1 3]
1330
+ ]
1331
+ sage: M=ntl.mat_ZZ(4,4,[-6,9,-15,-18,4,-6,10,12,10,-16,18,35,-24,36,-46,-82]); M
1332
+ [
1333
+ [-6 9 -15 -18]
1334
+ [4 -6 10 12]
1335
+ [10 -16 18 35]
1336
+ [-24 36 -46 -82]
1337
+ ]
1338
+ sage: M.LLL_FP()
1339
+ 3
1340
+ sage: M
1341
+ [
1342
+ [0 0 0 0]
1343
+ [0 -2 0 0]
1344
+ [-2 1 -5 -6]
1345
+ [0 -1 -7 5]
1346
+ ]
1347
+
1348
+ WARNING: This method modifies \code{self}. So after applying this
1349
+ method your matrix will be a vector of vectors.
1350
+ """
1351
+ cdef ntl_mat_ZZ U
1352
+ if return_U:
1353
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1354
+ sig_on()
1355
+ rank = int(mat_ZZ_LLL_FP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1356
+ sig_off()
1357
+ return rank, U
1358
+ else:
1359
+ sig_on()
1360
+ rank = int(mat_ZZ_LLL_FP(self.x,float(delta),0,0,int(verbose)))
1361
+ sig_off()
1362
+ return rank
1363
+
1364
+ def LLL_QP(self, delta, return_U=False, verbose=False):
1365
+ r"""
1366
+ Perform the same reduction as \code{self.LLL_FP} using the
1367
+ same calling conventions but with quad float precision.
1368
+
1369
+ EXAMPLES::
1370
+
1371
+ sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
1372
+ sage: M.LLL_QP(delta=0.75)
1373
+ 2
1374
+ """
1375
+ cdef ntl_mat_ZZ U
1376
+ if return_U:
1377
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1378
+ sig_on()
1379
+ rank = int(mat_ZZ_LLL_QP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1380
+ sig_off()
1381
+ return rank, U
1382
+ else:
1383
+ sig_on()
1384
+ rank = int(mat_ZZ_LLL_QP(self.x,float(delta),0,0,int(verbose)))
1385
+ sig_off()
1386
+ return rank
1387
+
1388
+ def LLL_XD(self, delta, return_U=False, verbose=False):
1389
+ r"""
1390
+ Perform the same reduction as \code{self.LLL_FP} using the
1391
+ same calling conventions but with extended exponent double
1392
+ precision.
1393
+
1394
+ EXAMPLES::
1395
+
1396
+ sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
1397
+ sage: M.LLL_XD(delta=0.75)
1398
+ 2
1399
+ """
1400
+ cdef ntl_mat_ZZ U
1401
+ if return_U:
1402
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1403
+ sig_on()
1404
+ rank = int(mat_ZZ_LLL_XD_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1405
+ sig_off()
1406
+ return rank, U
1407
+ else:
1408
+ sig_on()
1409
+ rank = int(mat_ZZ_LLL_XD(self.x,float(delta),0,0,int(verbose)))
1410
+ sig_off()
1411
+ return rank
1412
+
1413
+ def LLL_RR(self, delta, return_U=False, verbose=False):
1414
+ r"""
1415
+ Perform the same reduction as \code{self.LLL_FP} using the
1416
+ same calling conventions but with arbitrary precision floating
1417
+ point numbers.
1418
+
1419
+ EXAMPLES::
1420
+
1421
+ sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
1422
+ sage: M.LLL_RR(delta=0.75)
1423
+ 2
1424
+ """
1425
+ cdef ntl_mat_ZZ U
1426
+ if return_U:
1427
+ U = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
1428
+ sig_on()
1429
+ rank = int(mat_ZZ_LLL_RR_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1430
+ sig_off()
1431
+ return rank, U
1432
+ else:
1433
+ sig_on()
1434
+ rank = int(mat_ZZ_LLL_RR(self.x,float(delta),0,0,int(verbose)))
1435
+ sig_off()
1436
+ return rank
1437
+
1438
+ # Givens Orthogonalization. This is a bit slower, but generally
1439
+ # much more stable, and is really the preferred orthogonalization
1440
+ # strategy. For a nice description of this, see Chapter 5 of
1441
+ # [G. Golub and C. van Loan, Matrix Computations, 3rd edition,
1442
+ # Johns Hopkins Univ. Press, 1996].
1443
+
1444
+ def G_LLL_FP(self, delta, return_U=False, verbose=False):
1445
+ r"""
1446
+ Perform the same reduction as self.LLL_FP using the same
1447
+ calling conventions but uses the Givens Orthogonalization.
1448
+
1449
+ Givens Orthogonalization. This is a bit slower, but generally
1450
+ much more stable, and is really the preferred
1451
+ orthogonalization strategy. For a nice description of this,
1452
+ see Chapter 5 of [G. Golub and C. van Loan, Matrix
1453
+ Computations, 3rd edition, Johns Hopkins Univ. Press, 1996].
1454
+ """
1455
+ cdef ntl_mat_ZZ U
1456
+ if return_U:
1457
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1458
+ sig_on()
1459
+ rank = int(mat_ZZ_G_LLL_FP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1460
+ sig_off()
1461
+ return rank, U
1462
+ else:
1463
+ sig_on()
1464
+ rank = int(mat_ZZ_G_LLL_FP(self.x,float(delta),0,0,int(verbose)))
1465
+ sig_off()
1466
+ return rank
1467
+
1468
+ def G_LLL_QP(self, delta, return_U=False, verbose=False):
1469
+ r"""
1470
+ Perform the same reduction as self.G_LLL_FP using the same
1471
+ calling conventions but with quad float precision.
1472
+ """
1473
+ cdef ntl_mat_ZZ U
1474
+ if return_U:
1475
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1476
+ sig_on()
1477
+ rank = int(mat_ZZ_G_LLL_QP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1478
+ sig_off()
1479
+ return rank, U
1480
+ else:
1481
+ sig_on()
1482
+ rank = int(mat_ZZ_G_LLL_QP(self.x,float(delta),0,0,int(verbose)))
1483
+ sig_off()
1484
+ return rank
1485
+
1486
+ def G_LLL_XD(self, delta, return_U=False, verbose=False):
1487
+ r"""
1488
+ Perform the same reduction as self.G_LLL_FP using the same
1489
+ calling conventions but with extended exponent double
1490
+ precision.
1491
+ """
1492
+ cdef ntl_mat_ZZ U
1493
+ if return_U:
1494
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1495
+ sig_on()
1496
+ rank = int(mat_ZZ_G_LLL_XD_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1497
+ sig_off()
1498
+ return rank, U
1499
+ else:
1500
+ sig_on()
1501
+ rank = int(mat_ZZ_G_LLL_XD(self.x,float(delta),0,0,int(verbose)))
1502
+ sig_off()
1503
+ return rank
1504
+
1505
+ def G_LLL_RR(self, delta, return_U=False, verbose=False):
1506
+ r"""
1507
+ Perform the same reduction as self.G_LLL_FP using the same
1508
+ calling conventions but with arbitrary precision floating
1509
+ point numbers.
1510
+ """
1511
+ cdef ntl_mat_ZZ U
1512
+ if return_U:
1513
+ U = ntl_mat_ZZ(self.__nrows, self.__nrows)
1514
+ sig_on()
1515
+ rank = int(mat_ZZ_G_LLL_RR_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
1516
+ sig_off()
1517
+ return rank, U
1518
+ else:
1519
+ sig_on()
1520
+ rank = int(mat_ZZ_G_LLL_RR(self.x,float(delta),0,0,int(verbose)))
1521
+ sig_off()
1522
+ return rank