passagemath-ntl 10.6.33__cp313-cp313-musllinux_1_2_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.

Potentially problematic release.


This version of passagemath-ntl might be problematic. Click here for more details.

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